1、简介
在 Vue.js 中我们可以使用Axios完成 Ajax 请求,Axios 是一个基于 Promise 的 HTTP 库
这篇文章的文字不多,基本都是代码,解释也都写在注释里面啦
有兴趣的朋友也可以直接去看看官方文档:http://www.axios-js.com/zh-cn/docs/
2、安装
(1)CDN
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>
(2)NPM
> npm install axios
3、GET 请求
<!DOCTYPE html> <html> <head> <title>Demo</title> <script src="https://unpkg.com/vue/dist/vue.js"></script> <script src="https://unpkg.com/axios/dist/axios.js"></script> </head> <body> <div id="app"> <p>{{ info }}</p> </div> <script> new Vue({ el: '#app', data: { info: null }, mounted: function () { let _this = this; // GET 方法原型: axios.get(url[, config]) // 可以在 URL 中添加参数 axios .get('http://www.httpbin.org/get?firstName=Steve&lastName=Jobs') .then(function (response) { _this.info = response.data; }) .catch(function (error) { console.log(error); }); } }) </script> </body> </html>
4、响应结构
当我们发送请求后,接收到的响应(response)究竟是个什么东西呢?下面让我们来看一看
{ // 服务器返回的数据 // http://www.httpbin.org 是一个用于测试请求的网站,它所返回的数据就是我们请求的信息 data: {}, // 状态码 status: 200, // 状态码对应的状态信息 statusText: "OK", // 响应头 headers: {}, // 为请求提供的配置信息 config: {} }
5、POST 请求
<!DOCTYPE html> <html> <head> <title>Demo</title> <script src="https://unpkg.com/vue/dist/vue.js"></script> <script src="https://unpkg.com/axios/dist/axios.js"></script> </head> <body> <div id="app"> <p>{{ info }}</p> </div> <script> new Vue({ el: '#app', data: { info: null }, mounted: function () { let _this = this; // POST 方法原型: axios.post(url[, data[, config]]) // 可以通过 data 添加参数 axios .post('http://www.httpbin.org/post', { firstName: 'Steve', lastName: 'Jobs' }) .then(function (response) { _this.info = response.data; }) .catch(function (error) { console.log(error); }); } }) </script> </body> </html>
5、请求配置
除了上面两种常见的用法,我们还可以给 axios()
方法传入一个配置对象,里面包含用于请求的相关配置
比如说,我们可以用这种方法发送一个简单的 GET 请求:
axios({ url: 'http://www.httpbin.org/get', method: 'get', params: { firstName: 'Steve', lastName: 'Jobs' } })
同样的,我们也可以用这种方法发送一个简单的 POST 请求:
axios({ url: 'http://www.httpbin.org/post', method: 'post', data: { firstName: 'Steve', lastName: 'Jobs' } })
此外,一些比较常用的配置项如下:
url
:请求 URL,唯一的必填项baseURL
:自动加在url
前,以便于url
使用相对路径method
:请求方法,默认为 getheaders
:请求头params
:请求参数paramsSerializer
:将params
序列化data
:请求数据transformRequest
:在发送请求前允许修改请求数据transformResponse
:在接收响应前允许修改响应数据timeout
:指定超时时间withCredentials
:表示跨域请求时是否需要使用凭证,默认为 falseauth
:表示使用 HTTP 基础验证并提供凭据responseType
:服务器响应的数据类型,默认为 jsonmaxContentLength
:服务器响应内容的最大长度
我们还可以为请求配置设置默认值:
// 例如,下面设置 baseURL 为 https://www.example.com axios.defaults.baseURL = 'https://www.example.com'
6、拦截器
我们 then()
或 catch()
之前拦截请求或响应,并对它们进行一些处理
// 添加请求拦截器 var RequestInterceptor = axios.interceptors.request.use(function (config) { // 对请求数据做点什么 return config; }, function (error) { // 对请求错误做点什么 return Promise.reject(error); }); // 添加响应拦截器 var ResponseInterceptor = axios.interceptors.response.use(function (response) { // 对响应数据做点什么 return response; }, function (error) { // 对响应错误做点什么 return Promise.reject(error); });
如果想移除拦截器,也很简单
// 移除请求拦截器 axios.interceptors.request.eject(RequestInterceptor); // 移除响应拦截器 axios.interceptors.response.eject(ResponseInterceptor);
7、并发请求
axios.all()
可以批量发送请求,然后等所有请求都返回结果时,才执行一个回调
axios.all([ asyncMethodOne(), asyncMethodTwo() ]) .then(axios.spread(function (resOne, resTwo) { // 现在两个异步请求 asyncMethodOne 和 asyncMethodTwo 都已完成 // resOne 和 resTwo 分别是两个请求返回的响应 }))
补充:最近在写 axios 的时候遇到 跨域问题,查了很久资料才最终解决,这里也写下来记录一下
问题是这样子的,就是我要在利用 @vue/cli
搭建的项目中使用 axios 请求第三方天气查询的接口
http://t.weather.sojson.com/api/weather/city/101280101(GET 请求,在浏览器打开可以直接看到返回结果)
然后,按照上面的套路,很容易就能写出下面的代码:
axios .get('http://t.weather.sojson.com/api/weather/city/101280101') .then(function(res) { console.log(res); }) .catch(function(err) { console.log(err); })
可是,当我们运行项目 npm run serve
,打开浏览器控制台查看结果的时候居然报错了,出错信息如下:
Access to XMLHttpRequest at ‘http://t.weather.sojson.com/api/weather/city/101280101’
from origin ‘http://localhost:8080’ has been blocked by CORS policy:
No ‘Access-Control-Allow-Origin’ header is present on the requested resource.
后来在网上查了一下才知道,由于同源策略的限制,我们是不能直接进行跨域请求的
所谓跨域请求,是指请求 URL 与当前页面 URL 的协议、域名、端口三者任意之一不同
那要怎么解决呢?以下就是利用 @vue/cli
搭建的项目在开发环境下使用 axios
进行跨域请求的解决方案
- 在项目的根目录下新建
vue.config.js
配置文件,并在文件中添加配置代码
// vue.config.js module.exports = { // 使用后端 API 服务器发送请求,这样可以避免跨域问题 devServer: { proxy: { // 自定义标识符,当请求以 '/sojson' 开头才使用代理 '/sojson': { // 目标主机的协议和域名 target: 'http://t.weather.sojson.com', ws: true, changeOrigin: true, // 路径重写,在发送请求时将 '^/sojson' 替换成 '' pathRewrite: { '^/sojson': '' } } } } }
- 使用
axios
发送请求,注意请求地址的变化
axios .get('/sojson/api/weather/city/101280101') .then(function(res) { console.log(res); }) .catch(function(err) { console.log(err); }) // 此时,请求 URL 为 '/sojson/api/weather/city/101280101' // 因为请求以 '/sojson' 开头,符合自定义标识符,所以使用代理 // 因为请求以 '/sojson' 开头,符合路径重写规则,所以将其替换为 '' // 拼接上目标主机的协议和域名 'http://t.weather.sojson.com' // 最终使用代理发送的请求为 'http://t.weather.sojson.com/api/weather/city/101280101'
- 最后重新启动项目
npm run serve
(重要),就可以实现跨域请求啦
再补充:最近又遇到一个问题,就是 GET 请求没有问题,但是 POST 请求却得不到正确的数据
比如说,我们通过 POST 请求有道翻译的接口:https://fanyi.youdao.com/translate
和上面一样,我们还是需要先解决跨域的问题,在 vue.config.js
文件写好配置就行
module.exports = { devServer: { proxy: { '/youdao': { target: 'https://fanyi.youdao.com', ws: true, changeOrigin: true, pathRewrite: { '^/youdao': '' } } } } }
然后,按照上面类似的写法使用 axios
axios({ url: '/youdao/translate', method: 'POST', data: { 'i': 'Hello', // 翻译的内容 'doctype': 'json', 'from': 'AUTO', 'to': 'AUTO' } }).then(function(res) { console.log(res); }).catch(function(err) { console.log(err); })
但是当运行项目时你会发现,我们得不到正确的数据,这时候我们只需要做一点小改动就好
import qs from 'qs' let fromData = { 'i': 'Hello', 'doctype': 'json', 'from': 'AUTO', 'to': 'AUTO' } axios({ url: '/youdao/translate', method: 'POST', // 设置请求头 content-type headers: { 'content-type': 'application/x-www-form-urlencoded' }, // 将对象序列化为 URL 形式 data: qs.stringify(fromData) }).then(function(res) { console.log(res); }).catch(function(err) { console.log(err); })
文章知识点与官方知识档案匹配,可进一步学习相关知识