前言

前端现在使用三大框架来开发时,如果要发生网络请求(ajax)使用以前的 JQuery 来操作的,非常的不明智。有点杀鸡有牛刀的感觉。 这时就涌现了很多的网络请求工具,体积小,专注于发送网路请求。就很方便。

  1. angularjs 使用内置的 http 模块
  2. vuejs 使用 vue-resource、fetch、axios
  3. react 使用 fetch、axios

vue-resource

vue1.x 的时候,发送网络请求的一个插件。vue2.x 的时候,尤雨溪大大推荐我们使用 axios。vue-resource 不再维护。(不想重复的去造轮子)

安装 vue-resource

  1. $ npm install vue-resource

使用

  1. // main.js
  2. // 引入 Vue
  3. // 引入 vue-resource
  4. // 使用 Vue.use() 调用 vue-resource
  5. // 使用 Vue.http 或者 this.$http

语法

  1. this.$http.get(url, [options]).then().catch()
  2. this.$http.post(url, [body], [options]).then().catch()
  3. this.$http(options).then().catch()

fetch

ES6提供的。一个底层的请求API。用来替代 XMLHttpRequest 这个API 的。

安装 fetch

不需要额外安装,因为 fetch 是底层API。 但是 fetch 它有一些兼容性的问题。如果要处理兼容性问题时,就可以去安装一个 Polyfill

语法

  1. fetch(url).then(response => response.json()).then().catch()
  2. fetch(url).then(response => response.text()).then().catch()

axios

一款基于 XMLHttpRequest 对象封装的网络请求工具。同时支持浏览器端与Node端。集成了 Promise

参考文档

特点

  • 从浏览器中创建 XMLHttpRequest
  • 从 node.js 创建 http 请求
  • 支持 Promise API
  • 拦截请求和响应
  • 转换请求数据和响应数据
  • 取消请求
  • 自动转换 JSON 数据
  • 客户端支持防御 XSRF

安装 axios

  1. $ npm install axios

语法

  1. axios.get(url, [options]).then().catch()
  2. axios.post(url, [body], [options]).then().catch()
  3. ...
  4. axios(options).then().catch()

问题

1. 请求完成,发现 res 不是后台给我的数据?

axios 的 响应数据不是接口直接的响应。而是axios的一个包装对象。这个对象结构如下

  1. {
  2. // 这个属性,才是接口的响应
  3. data: {},
  4. // 响应的状态码
  5. status: 200,
  6. // 响应的状态信息
  7. statusText: 'OK',
  8. // 响应头信息
  9. headers: {},
  10. // 请求的一些配置信息
  11. config: {},
  12. // XMLHttpRequest 对象的一些信息
  13. request: {}
  14. }

2. GET请求需要传参时,后台告诉我参数不对,没有接受到参数?

看一下 network 是否真的传递了参数,确保一下 axios 的问号参数是通过 params 配置项传递的。 或者直接将参数拼接在 url 地址上。

3. POST请求时,后台告诉我参数接受不到?

  1. 先确保我们前端参数传递正确了 (看语法有没有写错)
  2. 询问后台是否支持 json 格式的数据(axios,默认都是一个json格式的数据传输)
    1. 方案一、让后台支持一下 json 格式
    2. 方案二、前端自己对参数做转化,转换成 key1=value1&key2=value2 这种格式的数据。使用 transformRequest 这个配置项

4. 后台的一些接口中,需要前端在请求头中传递token,如何优雅的去做呢?

普通方案:在请求时配置 headers 这个配置项
优雅方案:对 axios 做一些默认配置

  1. axios.defaults.headers = { token: '123456' } // 不要这样写,覆盖了默认的 headers
  2. axios.defaults.headers['token'] = '123456' // 这样写,才对

5. 第4点中,我们的token是写死的。正常token应该是要灵活设置才对?

拦截器的语法:

  1. // 添加请求拦截器
  2. axios.interceptors.request.use(function (config) {
  3. // 在发送请求之前做些什么
  4. return config;
  5. }, function (error) {
  6. // 对请求错误做些什么
  7. return Promise.reject(error);
  8. });
  9. // 添加响应拦截器
  10. axios.interceptors.response.use(function (response) {
  11. // 对响应数据做点什么
  12. return response;
  13. }, function (error) {
  14. // 对响应错误做点什么
  15. return Promise.reject(error);
  16. });

在请求拦截中处理

  1. axios.interceptors.request.use(function (config) {
  2. // 在发送请求之前做些什么
  3. if (window.localStorage.getItem('token')) {
  4. config.headers.token = window.localStorage.getItem('token')
  5. }
  6. return config
  7. }, function (error) {
  8. // 对请求错误做些什么
  9. return Promise.reject(error)
  10. })

6. 每次要得到后台的响应结果时,都是通过 res.data 获取的。能不能直接通过 res 获取呢?

在响应拦截中处理

  1. axios.interceptors.response.use(function (response) {
  2. // 对响应数据做点什么
  3. return response.data
  4. }, function (error) {
  5. // 对响应错误做点什么
  6. return Promise.reject(error)
  7. })

7. 每个文件都要单独去引入一下 axios 好麻烦。能不能像 vue-resource 一样。类似通过 this.$http 去用呢?

将 axios 挂载到 Vue 的原型上即可

  1. // main.js
  2. import Vue from 'vue'
  3. import axios from 'axios'
  4. Vue.prototype.$axios = axios