axios
axios文档
axios 是一个基于Promise 用于浏览器和 nodejs 的 HTTP 客户端
- 从浏览器中创建 XMLHttpRequests
- 从 node.js 创建 http 请求
- 支持 Promise API
- 拦截请求和响应
- 转换请求数据和响应数据
- 取消请求
- 自动转换 JSON 数据
- 客户端支持防御 XSRF
看起来就很高大上,就决定是它了;但用起来脑子石化,一脸黑人问号,经脉逆流…但是惹不起还是得惹,毕竟它非常流行
axios使用处理错误的写法
- 一个不建议的处理发生错误的代码
axios.get(url)
.then(response => {
console.log(response);
}, error => {
console.log(error);
})
这不是处理catch的相关,是关于new Promise()的then,将Promise对象的状态从“未完成”变为“失败”(即从 pending 变为 rejected),在异步操作失败时调用,并将异步操作报出的错误,作为参数传递出去。
2. catch是处理逻辑或接口出错
axios.get(url)
.then(res=>{
//处理业务逻辑
})
.catch(err=>{
})
- catch的分步骤处理
if (error.response) {
// 请求已发出,但服务器响应的状态码不在 2xx 范围内
console.log(error.response.data);
console.log(error.response.status);
console.log(error.response.headers);
} else if (error.request) {
// 有请求但未收到响应
console.log(error.request);
} else {
// 在发生请求时触发的错误
console.log('Error', error.message);
}
console.log(error.config);
vue cli 2使用axios
- 安装脚手架
cnpm install -g @vue/cli-service-global
- 现在是vue cli 3,所以我们需要全局安装一个桥接工具
cnpm install -g @vue/cli-init
- 可以自主选择,根据自己需求,这里选择默认的,然后下载包,最后更改App.vue的内容
vue init webpack axios_test
cnpm i
- 下载axios
cnpm i axios -S
- 提供接口:这里使用某度音乐做测试接口
http://tingapi.ting.baidu.com/v1/restserver/ting?method=baidu.ting.billboard.billList&type=1&size=10&offset=0
- 在main.js导入并配置
import Axios from 'axios'
Vue.prototype.$axios = Axios
- App.vue测试
export default {
mounted(){
this.$axios.get('http://tingapi.ting.baidu.com/v1/restserver/ting?method=baidu.ting.billboard.billList&type=1&size=10&offset=0')
.then(result=>{
console.log(result)
})
.catch(error=>{
console.log(error)
})
}
};
- 运行项目
cnpm run dev
我用铜钱算出来你报了一下的错误;这是因为浏览器的同源政策
Access to XMLHttpRequest at 'http://tingapi.ting.baidu.com/v1/restserver/ting?method=baidu.ting.billboard.billList&type=1&size=10&offset=0' from origin 'http://localhost:8080' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
解决跨域
我们先来实现解决跨域在解释(1.2是实现解决禁止跨域的)
- 在main.js加入HOST
Vue.prototype.$axios = Axios
Vue.prototype.HOST = '/baidu_music_api'
- 在配置文件config文件夹的index.js里面配置,在里面有个proxyTable配置
proxyTable: {
"/baidu_music_api": {
target: "http://tingapi.ting.baidu.com",
changeOrigin: true,
pathRewrite: {
'^/baidu_music_api': '/v1/restserver/ting'
}
}
},
- 重新再App.vue发送请求
mounted(){
let url = this.HOST + '?method=baidu.ting.billboard.billList&type=1&size=10&offset=0'
this.$axios.get(url)
.then(result=>{
console.log(result)
})
.catch(error=>{
console.log(error)
})
- 配置文件的解释
proxyTable在使用webpack做构建工具的项目中使用proxyTable代理实现跨域是一种比较方便的选择。
target目标接口域名
changeOrigin是否跨域
pathRewrite是重写接口,如果没有包含该项目名或则字段(/v1/restserver/ting)的话,我们可以直接写’/'来代替
比如大部分接口有’api’,我们配置的时候时候可以直接(这里跟我们当前接口使用的无关)
proxyTable: {
'/api': {
target: 'http://www.csdn.com', //目标接口域名
changeOrigin: true, //是否跨域
pathRewrite: {
'^/api': '/api' //重写接口
//没有api
// '^api':'/'
}
},
- 原理解释
'http://localhost:8080/baidu_music_api' ===> 'http://tingapi.ting.baidu.com/v1/restserver/ting'
本地服务器 --》 代理 --》目标服务器 --》拿到数据后通过代理伪装成本地服务请求的返回值 ---》然后浏览器就顺利收到了我们想要的数据
也就是说我们访问,会重写服务器http://tingapi.ting.baidu.com,baidu_music_api就会解析成v1/restserver/ting;有人说可以理解为服务器是没有同源政策的。
6. 接下来可以看一下我们返回的数据,直接截图
以下响应结构的信息;所以我们的数据都要在data里面获取
{
// `data` 由服务器提供的响应
data: {},
// `status` 来自服务器响应的 HTTP 状态码
status: 200,
// `statusText` 来自服务器响应的 HTTP 状态信息
statusText: 'OK',
// `headers` 服务器响应的头
headers: {},
// `config` 是为请求提供的配置信息
config: {}
}
- 添加拦截器
页面发送http请求,很多情况我们要对请求和其响应进行特定的处理;如果请求数非常多,单独对每一个请求进行处理会变得非常麻烦,程序的优雅性也会大打折扣。axios为开发者提供了这样一个API:拦截器。拦截器分为 请求(request)拦截器和 响应(response)拦截器。
应用场景:路由拦截、统一处理所有的http请求和响应、refresh_token换access_token
Vue.prototype.HOST = '/baidu_music_api'
// 添加请求拦截器
Axios.interceptors.request.use(function (config) {
if(config.method === "post"){
config.data = qs.stringify(config.data)
}
return config;
}, function (error) {
// 对请求错误做些什么
return Promise.reject(error);
});
// 添加响应拦截器
Axios.interceptors.response.use(function (response) {
// 对响应数据做点什么
return response;
}, function (error) {
// 对响应错误做点什么
return Promise.reject(error);
});
vue cli3使用
vue cli参考配置vue.config.js的devServer配置
可以自主配置(空格是选中),也可以直接选择默认
vue create axios_vue3
- 项目根目录下新建vue.config.js
vue.config.js 是一个可选的配置文件,如果项目的 (和 package.json 同级的) 根目录中存在这个文件,那么它会被 @vue/cli-service 自动加载。
- 接着在main.js的文档里面配置(先安装axios)
import Axios from 'axios'
Vue.prototype.$axios = Axios
Vue.prototype.HOST = '/api'
- 在vue.config.js里面配置
module.exports = {
devServer: {
proxy: {
'/api': {
target: 'http://tingapi.ting.baidu.com/v1/restserver/ting',
ws: true,
changeOrigin: true
}
}
}
}
- 测试axios
mounted(){
let url = this.HOST + '?method=baidu.ting.billboard.billList&type=1&size=10&offset=0'
this.$axios.get(url).then(result=>{
console.log(result)
})
}
直接使用webpack,没有使用脚手架的,看看这个能否解决
https://webpack.js.org/configuration/dev-server/#devserverproxy