内容简介:axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。使用npm使用cdn
axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中。
axios的功能和特征:
- 从浏览器中创建XMLHttpRequests
- 从node.js中创建http请求
- 支持PromiseAPI
- 拦截请求和响应
- 转换请求数据和响应数据
- 取消请求
- 自动转化JSON数据
- 客户端支持防御XSRF
在项目中安装axois
使用npm
npm install axios --save 复制代码
使用cdn
<script src="https://unpkg.com/axios/dist/axios.min.js"></script> 复制代码
使用demo
-
执行GET请求,当执行GET方式时,如果携带请求参数,请求参数可以有两种方式:
axios.get('/user?ID=12121').then((response)=> { //response }).catch((error)=> { //error }); 或者 axios.get('/user',{ params: { ID: 12121 } }).then((response)=> { //response }).catch((error)=> { //error }); 复制代码
-
执行POST请求
axios.post('/user',{ name: '12121' }).then((response) => { //reponse }).catch((error) => { //error }); 复制代码
-
执行多个并发请求
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){ //两个请求现在都执行完成 }) ); 复制代码
上面这种写法都是通过axios.get/post这种写法,这种写法稍微有点麻烦,可以通过这种写法,通过axios传递相关配置来创建请求。同时axios的默认的请求方式为GET方式。
axios({ url: apiURL, method: method, timeout: timeout, data: data, params: params, headers: { 'Content-Type': 'application/json', 'token': window.sessionStore.getItem('token') || '' } }); 复制代码
当处理并发的方式时:
- axios.all(iterable)
- axios.spread(callback)
同时axios也支持通过自定义配置创建一个axios示例
语法: axios.create([config])
var instance = axios.create({ baseURL: 'https://some-domain.com/api/', timeout: 1000, headers: {'X-Custom-Header': 'foobar'} }); 复制代码
相关的请求配置
这些是创建请求时可以用的配置选项。只有 url
是必需的。如果没有指定 method
,请求将默认使用 get
方法。
//'url'是用于请求服务器的URL url: '/user', //'method'是创建请求时使用的方法 method: 'get', //默认是get //'baseUrl'将自动加在'url'前面,除非'url'是一个绝对url //它可以通过设置一个 `baseURL` 便于为 axios 实例的方法传递相对 URL baseURL: 'https://some-domain.com/api/', //'transformRequest'允许向服务器发送前,修改请求数据 //只能用在put、post、patch这几个请求方法 //后面数组中的函数必须返回一个字符串,或ArrayBuffer,或Stream transformRequest: [function (data){ //对data进行任意转换处理 return data; }], //'transformResponse'在传递then/catch前,允许修改响应数据 transformResponse: [function (data){ // 对data进行任意的转换 return data; }], //'headers'是即将被发送的自定义请求头 headers: {'X-Requested-With': 'XMLHttpRequest'}, //'params'是即将与请求一起发送的url参数 //必须是一个无格式对象(plain object)或 URLSearchParams对象 params: { ID: 12345 }, // `paramsSerializer` 是一个负责 `params` 序列化的函数 // (e.g. https://www.npmjs.com/package/qs, http://api.jquery.com/jquery.param/) paramsSerializer: function(params) { return Qs.stringify(params, {arrayFormat: 'brackets'}) }, // 'data'是作为请求主体被发送的数据 // 只适用于这些请求方法(put,post,patch) // 在没有设置 `transformRequest` 时,必须是以下类型之一: // string, plain object, ArrayBuffer, ArrayBufferView, URLSearchParams // - 浏览器专属:FormData, File, Blob // - Node 专属: Stream data: { name: '1212' }, // `timeout` 指定请求超时的毫秒数(0 表示无超时时间) // 如果请求话费了超过 `timeout` 的时间,请求将被中断 timeout: 1000, // `withCredentials` 表示跨域请求时是否需要使用凭证 withCredentials: false, // 默认的 // `adapter` 允许自定义处理请求,以使测试更轻松 // 返回一个 promise 并应用一个有效的响应 (查阅 [response docs](#response-api)). adapter: function (config) { /* ... */ }, // `auth` 表示应该使用 HTTP 基础验证,并提供凭据 // 这将设置一个 `Authorization` 头,覆写掉现有的任意使用 `headers` 设置的自定义 `Authorization`头 auth: { username: 'janedoe', password: 's00pers3cret' }, // 'responseType'表示服务器响应的数据类型,可以是arraybuffer,blob,document,json,text,stream responseType: 'json', 复制代码
响应结构
某个请求的响应包含以下信息:
{ // `data` 由服务器提供的响应 data: {}, // `status` 来自服务器响应的 HTTP 状态码 status: 200, // `statusText` 来自服务器响应的 HTTP 状态信息 statusText: 'OK', // `headers` 服务器响应的头 headers: {}, // `config` 是为请求提供的配置信息 config: {} } 复制代码
在实际的开发过程中后台的接口会遵循RESTful规范,同时会自己封装数据的返回格式,例如是下面这种格式:
也就是说我们取出的数据是从response.data中去拿到,然后按一定的格式取,一般后台的数据的封装格式如下:
新建一个util的包:
MessageEntity类:
package com.ssm.util; import lombok.Data; @Data public class MessageEntity<T> { private Integer code; private String msg; private T data; private Integer total; } 复制代码
MessageCode类:
package com.ssm.util; public enum MessageCode { SYSTEM_CODE(500, "系统错误"); private Integer code; private String message; public Integer getCode() { return code; } public String getMessage() { return message; } MessageCode(Integer code, String message) { this.code = code; this.message = message; } } 复制代码
ResultForma类:
package com.ssm.util; public class ResultFormat { public static MessageEntity success() { return success(null); } public static <T> MessageEntity<T> success(T t){ MessageEntity msg = new MessageEntity(); msg.setCode(200); msg.setMsg("操作成功"); msg.setData(t); return msg; } public static MessageEntity error(MessageCode message) { MessageEntity msg = new MessageEntity(); msg.setCode(message.getCode()); msg.setMsg(message.getMessage()); return msg; } } 复制代码
配置默认值
- 全局的axios默认值
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'; 复制代码
- 自定义实例默认值
// 创建实例时设置配置的默认值 var instance = axios.create({ baseURL: 'https://api.example.com' }); // 在实例已创建后修改默认值 instance.defaults.headers.common['Authorization'] = AUTH_TOKEN; 复制代码
- 配置的优先顺序
配置会以一个优先顺序进行合并。这个顺序是:在 lib/defaults.js
找到的库的默认值,然后是实例的 defaults
属性,最后是请求的 config
参数。后者将优先于前者。这里是一个例子:
// 使用由库提供的配置的默认值来创建实例 // 此时超时配置的默认值是 `0` var instance = axios.create(); // 覆写库的超时默认值 // 现在,在超时前,所有请求都会等待 2.5 秒 instance.defaults.timeout = 2500; // 为已知需要花费很长时间的请求覆写超时设置 instance.get('/longRequest', { timeout: 5000 }); 复制代码
拦截器
在请求或响应被 then
或 catch
处理前拦截它们。
// 添加请求拦截器 axios.interceptors.request.use(function (config) { // 在发送请求之前做些什么 return config; }, function (error) { // 对请求错误做些什么 return Promise.reject(error); }); // 添加响应拦截器 axios.interceptors.response.use(function (response) { // 对响应数据做点什么 return response; }, function (error) { // 对响应错误做点什么 return Promise.reject(error); }); 复制代码
如果你想在稍后移除拦截器,可以这样:
var myInterceptor = axios.interceptors.request.use(function () {/*...*/}); axios.interceptors.request.eject(myInterceptor); 复制代码
取消
可以使用 CancelToken.source
工厂方法创建 cancel token,像这样:
var CancelToken = axios.CancelToken; var source = CancelToken.source(); axios.get('/user/12345', { 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.'); 复制代码
axios源码学习
找到axios下面的lib/axios.js文件
lib/axios.js中代码创建实例代码分析:
// lib/axios.js function createInstance(defaultConfig) { // 创建一个Axios实例 var context = new Axios(defaultConfig); // 以下代码也可以这样实现:var instance = Axios.prototype.request.bind(context); // 这样instance就指向了request方法,且上下文指向context,所以可以直接以 instance(option) 方式调用 // Axios.prototype.request 内对第一个参数的数据类型判断,使我们能够以 instance(url, option) 方式调用 var instance = bind(Axios.prototype.request, context); // 把Axios.prototype上的方法扩展到instance对象上, // 这样 instance 就有了 get、post、put等方法 // 并指定上下文为context,这样执行Axios原型链上的方法时,this会指向context utils.extend(instance, Axios.prototype, context); // 把context对象上的自身属性和方法扩展到instance上 // 注:因为extend内部使用的forEach方法对对象做for in 遍历时,只遍历对象本身的属性,而不会遍历原型链上的属性 // 这样,instance 就有了 defaults、interceptors 属性。(这两个属性后面我们会介绍) utils.extend(instance, context); return instance; } // 接收默认配置项作为参数(后面会介绍配置项),创建一个Axios实例,最终会被作为对象导出 var axios = createInstance(defaults); 复制代码
-
拦截器 interceptors
拦截器分为请求拦截器(interceptors.request)和响应拦截器(interceptors.response)。
请求拦截器(
interceptors.request
)是指可以拦截住每次或指定http请求,并可修改配置项 ;响应拦截器(
interceptors.response
)是指http请求后拦截,并可修改返回结果项; -
数据转换器
数据转换器分为请求转换器和响应转换器,顾名思义: 请求转换器(
transformRequest
)是指在请求前对数据进行转换, 响应转换器(transformResponse
)主要对请求响应后的响应体做数据转换。 -
http请求适配器
-
config配置项
axios流程图
axios多种使用方式:
- 第1种使用方式:
axios(option)
axios({ url, method, headers, }) 复制代码
- 第2种使用方式:
axios(url[, option])
axios(url, { method, headers, }) 复制代码
- 第3种使用方式(对于
get、delete
等方法):axios[method](url[, option])
axios.get(url, { headers, }) 复制代码
- 第4种使用方式(对于
post、put
等方法):axios[method](url[, data[, option]])
axios.post(url, data, { headers, }) 复制代码
- 第5种使用方式:
axios.request(option)
axios.request({ url, method, headers, }) 复制代码
用户配置项对象config
http请求适配器、请求地址、请求方法、请求头header、 请求数据、请求或响应数据的转换、请求进度、http状态码验证规则、超时、取消请求等。可以发现,几乎 axios
所有的功能都是通过这个对象进行配置和传递的, 既是 axios
项目内部的沟通桥梁,也是用户跟 axios
进行沟通的桥梁。
import axios from 'axios' // 第1种:直接修改Axios实例上defaults属性,主要用来设置通用配置 axios.defaults[configName] = value; // 第2种:发起请求时最终会调用Axios.prototype.request方法,然后传入配置项,主要用来设置“个例”配置 axios({ url, method, headers, }) // 第3种:新建一个Axios实例,传入配置项,此处设置的是通用配置 let newAxiosInstance = axios.create({ [configName]: value, }) 复制代码
跨域携带cookie
import axios from 'axios' axios.defaults.withCredentials = true; 复制代码
在react项目中对axios简单封装使用
命名三个文件Api.js、ApiURL.js、ApiIp.js,其中ApiIp.js是用来获取服务器ip地址的,ApiURL.js是用来拼装ip地址和接口路径的,当然这个可以使用baseURL来实现也可以,即:axios.defaults.baseURL = 'api.example.com';
Api.js的实现
import axios from 'axios'; import {notification} from 'antd'; import * as ApiURL from 'src/HttpClientRequest/ApiURL'; const key = 'keepOnlyOne'; /** * 数据请求公共方法 * @param apiURL 接口请求路径 * @param configObj 用户传入配置的参数 * @returns {Promise<any>} */ function getDataFromServer(apiURL, configObj) { // 获取用户传入的接口配置参数 let { method = 'get', data = {}, timeout = 3000, params = {} } = configObj; return new Promise(function (resolve, reject) { axios({ url: apiURL, method: method, timeout: timeout, data: data, params: params, headers: { 'Content-Type': 'application/json', 'token': window.sessionStore.getItem('token') || '' } }).then((response) => { if (response) { if (response.data && response.data.code) { resolve(response); } else { notification.error({ key, message: '操作失败', description: '数据格式有误' }); resolve(response); } } else { notification.error({ key, message: '操作失败', description: '服务器错误' }); resolve(response); } }).catch((error) => { notification.error({ key, message: '操作失败', description: '网络异常,请稍后重试' }); reject(error); }); }); } export function login(configObj) { return getDataFromServer(ApiURL.LOGIN, configObj); } 复制代码
ApiURL.js
import API_IP from './ApiIp'; // 登录接口地址 export const LOGIN = `${API_IP}/index/login`; 复制代码
ApiIp.js
// 获取当前浏览器的地址 const interfaceIp = window.location.host; const imageAddrassIp = window.location.hostname; // 获取当前浏览器的协议 const browserProtocol = window.location.protocol; // 进行服务器请求地址的封装 const serverInterfaceIp = `${browserProtocol}//${interfaceIp}`; const serverImageIp = `${browserProtocol}//${imageAddrassIp}`; // 对外提供的请求地址(兼容生产环境和开发环境) export const API_IP = process.env.NODE_ENV === 'development' ? 'http://121.0.0.1:8080' : serverInterfaceIp; export const IMAGES_IP = process.env.NODE_ENV === 'development' ? 'http://121.0.0.1' : serverImageIp; 复制代码
参考文章: juejin.im/post/5cb5d9…
以上就是本文的全部内容,希望本文的内容对大家的学习或者工作能带来一定的帮助,也希望大家多多支持 码农网
猜你喜欢:- 【每日笔记】【Go学习笔记】2019-01-04 Codis笔记
- 【每日笔记】【Go学习笔记】2019-01-02 Codis笔记
- 【每日笔记】【Go学习笔记】2019-01-07 Codis笔记
- Golang学习笔记-调度器学习
- 算法/NLP/深度学习/机器学习面试笔记
- ES学习笔记之-ClusterState的学习
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
构建之法(第三版)
邹欣 / 人民邮电出版社 / 2017-6 / 69.00元
软件工程牵涉的范围很广, 同时也是一般院校的同学反映比较空洞乏味的课程。 但是,软件工程 的技术对于投身 IT 产业的学生来说是非常重要的。作者有在世界一流软件企业 20 年的一线软件开 发经验,他在数所高校进行了多年的软件工程教学实践,总结出了在 16 周的时间内让同学们通过 “做 中学 (Learning By Doing)” 掌握实用的软件工程技术的教学计划,并得到高校师生的积极反馈。在此 ......一起来看看 《构建之法(第三版)》 这本书的介绍吧!