这篇文章去年5月就写了,还差一点没收尾,觉得写的不好放在日记本里没发布,今天就发了吧,重点看我axios的那个长长的例子。初学者如果看不懂私信我吧。。有错误也请大佬拍砖,毕竟我已经心不在焉的去考公了,做项目只想完成功能就算了,心不在这里啊。。。 `vue-resource`早已不再更新!尤大大推荐用**axios**!! 这里还是先简单说一下vue-resource。 >   vue-resource是Vue.js的一款插件,它可以通过XMLHttpRequest或JSONP发起请求并处理响应。也就是说,Ajax能做的事情,vue-resource插件一样也能做到,而且vue-resource的API更为简洁。划重点,vue-resource还提供了非常有用的inteceptor(拦截器)功能(经常使用),使用inteceptor可以在请求发送前和发送请求后做一些处理,比如使用inteceptor在ajax请求时显示loading界面,或者在请求发送前在headers中设置token,加入token验证,拦截器在axios中详细介绍。 ### 一、简单介绍vue-resource用法 ##### 1.引入 ~~~jsx import Vue from 'vue' import VueResource from 'vue-resource' Vue.use(VueResource) ~~~ ##### 2.使用 引入vue-resource后,可以基于全局的Vue对象使用http,也可以基于某个Vue实例使用http。 ~~~tsx 在一个Vue实例内使用$http this.$http.get('/Url', [options]).then((response) => { // 响应成功回调 }, (response) => { // 响应错误回调 }); ~~~ ##### 3.跨域 解决vue-resource post请求跨域问题: vue提供了一个简单的解决方法,就是 `Vue.http.options.emulateJSON = true` 其实等同于在headers中添加 'Content-Type': 'application/x-www-form-urlencoded'。 注意:$http请求和jquery中使用ajax还是有点区别,这里的post的data默认不是以`form data`的形式,而是`request payload`。所以你们别忘了将emulateJSON 属性设置为true,即可解决这个问题。`Vue.http.options.emulateJSON = true` form data和request payload的区别: * form date get请求,是将请求参数以&方法,拼接在url后面,如:[http://www.dxl.com?name=dxl&password=8888](https://links.jianshu.com/go?to=http%3A%2F%2Fwww.dxl.com%3Fname%3Ddxl%26password%3D8888); 真正可以明显看出区分的是在post请求上, post请求时,头文件 中Content-Type 是默认值 application/x-www-form-urlencoded,参数是放在 `form date`中的。 * request payload post请求时,头文件 中Content-Type 是默认值 application/json;charset=UTF-8,参数是放在 `request payload` 中的。 ~~~jsx JSONP请求: getJsonp: function() { this.$http.jsonp(this.apiUrl).then(function(response){ this.$set('gridData', response.data) }) } ~~~ ##### 4.resource服务 `vue-resource`提供了另外一种方式访问HTTP——resource服务 resource对象也有两种访问方式: 全局访问:Vue.resource 实例访问:this.$resource (1)get请求 ~~~tsx getCustomers: function() { var resource = this.$resource(this.apiUrl) vm = this resource.get() .then((response) => { vm.$set('gridData', response.data) }) .catch(function(response) { console.log(response) }) } ~~~ (2)post请求 使用save方法发送POST请求。 ~~~jsx createCustomer: function() { var resource = this.$resource(this.apiUrl) vm = this resource.save(vm.apiUrl, vm.item) .then((response) => { vm.$set('item', {}) vm.getCustomers() }) this.show = false } ~~~ (3)使用update方法发送PUT请求,使用remove或delete方法发送DELETE请求 ##### 5.拦截器interceptors ~~~jsx Vue.http.interceptors.push((request, next) => { // ... // 请求发送前的处理逻辑 // ... next((response) => { // ... // 请求发送后的处理逻辑 // ... // 根据请求的状态,response参数会返回给successCallback或errorCallback return response }) }) ~~~ ### 二、axios ##### 1.介绍 > Axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。 > 看这个吧,传送门→[https://www.kancloud.cn/yunye/axios/234845](https://links.jianshu.com/go?to=https%3A%2F%2Fwww.kancloud.cn%2Fyunye%2Faxios%2F234845) > axios支持IE8。 它可以: * 从浏览器中创建 `XMLHttpRequests` * 从 node.js 创建 `http`请求 * 支持 Promise API * 拦截请求和响应 * 转换请求数据和响应数据 * 取消请求 * 自动转换 JSON 数据 * 客户端支持防御 `XSRF` (1)get请求 ~~~jsx axios.get('/user', { params: { ID: 1111 } }) .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); }); // 还可以这么写,es7新特性async/await async function getUser() { try { const response = await axios.get('/user?ID=1111'); console.log(response); } catch (error) { console.error(error); } } *async用于声明一个函数是异步的,而await是“等待”的意思,就是用于等待异步完成。 await只能在async函数中使用。 await可以让js进行等待,直到一个promise执行并返回它的结果,js才会继续往下执行。 async/await 面试经常问到哦,百度查一下,划重点 ~~~ (2)post请求 ~~~jsx axios.post('/user', { firstName: 'xiliDong', lastName: 'dongxili' }) .then(function (response) { console.log(response); }) .catch(function (error) { console.log(error); }); //或者这样写 axios({ method: 'post', url: '/user', data: { firstName: 'xiliDong', lastName: 'dongxili' } }); ~~~ (3)执行多个并发请求 ~~~jsx function getUserAccount() { return axios.get('/user/12345'); } function getUserPermissions() { return axios.get('/user/12345/permissions'); } axios.all([getUserAccount(), getUserPermissions()]) .then(axios.spread(function (acct, perms) { // 两个请求现在都执行完成 })); ~~~ ##### 2.创建实例(重点) 可以使用自定义配置新建一个 axios 实例 ###### axios.create(\[config\]) ~~~csharp var instance = axios.create({ baseURL: 'https://some-domain.com/api/', timeout: 1000, headers: {'X-Custom-Header': 'foobar'} }); ~~~ ###### (1)响应结构: ~~~jsx { data: {}, // data由服务器提供的响应 status: 200, // 服务器响应的 HTTP 状态码 statusText: 'OK', // 服务器响应的 HTTP 状态信息 headers: {}, // 服务器响应的头 config: {} // 为请求提供的配置信息 } 使用 then 时,你将接收下面这样的响应: axios.get('/user/1111') .then(function(response) { console.log(response.data); console.log(response.status); console.log(response.statusText); console.log(response.headers); console.log(response.config); }); ~~~ ###### (2)指定配置的默认值: ~~~rust axios.defaults.baseURL = 'https://api.example.com'; axios.defaults.headers.common['Authorization'] = AUTH_TOKEN; axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded'; ~~~ * 自定义实例默认值: ~~~csharp // 创建实例时设置配置的默认值 var instance = axios.create({ baseURL: 'https://api.example.com' }); // 在实例已创建后修改默认值 instance.defaults.headers.common['Authorization'] = AUTH_TOKEN; ~~~ ###### (3)拦截器: (axios配置看我这个例子就差不多了) ~~~tsx // request拦截器 import axios from 'axios' import router from '../router' // 创建axios实例 const service = axios.create({ timeout: null // 请求超时时间 }) let serviceTips = '服务器超时' // request拦截器 service.interceptors.request.use( config => { // console.log(service.interceptors) // 获取本地token let token = localStorage.getItem('tokendata') // 设置请求头 let headers = 'application/json' // 是否携带token let tokenFlag = true // 是否修改请求信息 if (config.opts) { // 获取携带token状态 tokenFlag = config.opts ? config.opts.token : true // 获取请求头 headers = config.opts.Header ? config.opts.Header : 'application/json' // 拓展头部参数 let Head = config.opts.Head if (Head) { for (let key in Head) { config.headers[key] = Head[key] } } } // 暂时不加入token验证 // if (token && tokenFlag) { // // 条件允许,携带token请求 // config.headers['JSESSIONID'] = token // // config.headers['X-Auth0-Token'] = token // } else { // headers = 'application/x-www-form-urlencoded' // } // 设置请求格式 config.headers['Content-Type'] = headers return config }, err => { return Promise.reject(err) } ) // http response 服务器响应拦截器 service.interceptors.response.use( response => { return response }, error => { if (error.response) { switch (error.response.status) { case 401: error.response.data = '登陆超时,重新登陆' router.replace({ path: '/login', query: { redirect: router.currentRoute.fullPath } // 登录成功后跳入浏览的当前页面 }) break case 404: error.response.data = '资源不存在' break case 406: error.response.data = '头部无携带token' break case 412: // 拦截错误 并重新跳入登页重新获取token router.replace({ path: '/login', query: { redirect: router.currentRoute.fullPath } // 登录成功后跳入浏览的当前页面 }) error.response.data = '秘钥失效' localStorage.removeItem('tokendata') // 清除token break case 415: error.response.data = '请求type有误' break case 500: error.response.data = '服务器异常' break } serviceTips = error.response.data } Message.error(serviceTips) return Promise.reject(serviceTips) } ) export default service ~~~ ~~~jsx 配置好了怎么使用呢? 在api.js中引入拦截器: import fetch from '@/utils/fetch' // 拦截器 export function getList(obj) { const data = obj return fetch({ url: '', method: 'POST', data }) } -------------------------------- 可以使用 validateStatus 配置选项定义一个自定义 HTTP 状态码的错误范围。 export function getList(obj) { const data = obj return fetch({ url: '', method: 'POST', validateStatus: function(status) { // return status >= 200 && status < 300; // 默认的 return status < 500; // 状态码在大于或等于500时才会 reject }, data }) } ~~~ ~~~jsx 重点: axios的请求头默认为'application/json', 即axios会默认序列化 JavaScript 对象为 JSON. 如果想使用 application/x-www-form-urlencoded 格式,你可以使用下面的配置: import Qs from 'qs' export function getList(obj) { const data = Qs.stringify(obj) return fetch({ url: '', method: 'POST', headers: { 'content-type': 'application/x-www-form-urlencoded', // 如果需要XMLHttpRequest,加入这个 'X-Requested-With': 'XMLHttpRequest' }, data }) } ~~~ ~~~kotlin 然后在在vue文件中引入此函数来获取数据 // param为前端传入的参数 getList(param).then(res => { if (res.data.code === 0) { console.log(res.data.data); this.allOrderTable = res.data.data.data; this.pageTotal = res.data.data.total; } else { this.$message({ message: `[${res.data.msg}]:查询失败`, type: "error" }); } this.listLoading = false; }) .catch(() => {}) ~~~ 如果你想在稍后移除拦截器,可以这样: ~~~php var myInterceptor = axios.interceptors.request.use(function () {/*...*/}); axios.interceptors.request.eject(myInterceptor); ~~~ ###### (4)使用 cancel token 取消请求: (额,我好像没用到过(4)) 可以使用 `CancelToken.source` 工厂方法创建 `cancel token` ~~~jsx var CancelToken = axios.CancelToken; var source = CancelToken.source(); axios.get('/user/1111', { cancelToken: source.token }).catch(function(thrown) { if (axios.isCancel(thrown)) { console.log('Request canceled', thrown.message); } else { // 处理错误 } }); // 取消请求(message 参数是可选的) source.cancel('Operation canceled by the user.'); ~~~ 还可以通过传递一个 executor 函数到 CancelToken 的构造函数来创建 cancel token: ~~~jsx var CancelToken = axios.CancelToken; var cancel; axios.get('/user/12345', { cancelToken: new CancelToken(function executor(c) { // executor 函数接收一个 cancel 函数作为参数 cancel = c; }) }); // 取消请求 cancel(); 注意,还可以使用同一个 cancel token 取消多个请求 ~~~ 14人点赞 [技术文档](/nb/22744967) 作者:东西里 链接:[https://www.jianshu.com/p/65097586d1a2](https://www.jianshu.com/p/65097586d1a2) 来源:简书 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。