最新版本见 Github,点击查看历史版本
API
提供三种常用的便捷函数
- doAll ( iterable )
- ajax ( options )
- ~
- fetch ( url,options )
- fetchHead ( url,options )
- fetchDelete ( url,options )
- fetchJsonp ( url,params,options )
- fetchGet ( url,options )
- fetchPost ( url,body,options )
- fetchPut ( url,options )
- fetchPatch ( url,options )
- ~
- doHead ( url,options )
- doDelete ( url,options )
- doJsonp ( url,options )
- doGet ( url,options )
- doPost ( url,options )
- doPut ( url,options )
- doPatch ( url,options )
- ~
- headJSON ( url,options )
- deleteJSON ( url,options )
- jsonp ( url,options )
- getJSON ( url,options )
- postJSON ( url,options )
- putJSON ( url,options )
- patchJSON ( url,options )
入参
- url(字符串) 请求地址,可被自定义 options 属性覆盖
- params/body(可选,对象/数组) 要发送的数据,可被自定义 options 属性覆盖
- options (可选,对象) 参数
options 参数
*: 只支持最高版本的浏览器。
| 参数 | 类型 | 描述 | 默认值 |
|---|---|---|---|
| url | String | 请求地址 | |
| baseURL | String | 基础路径 | 默认上下文路径 |
| method | String | 请求方法 | 'GET' |
| params | Object/Array | 请求参数 | |
| body | Object/Array | 提交参数 | |
| bodyType | String | 提交参数方式,可以设置json-data,form-data | 'json-data' |
| mode | String | 请求的模式,可以设置cors,no-cors,same-origin | 'cors' |
| cache | String | 处理缓存方式,可以设置default,no-store,no-cache,reload,force-cache,only-if-cached | 'default' |
| credentials | String | 设置 cookie 是否随请求一起发送,可以设置: omit,same-origin,include | 'same-origin' |
| * redirect | String | 重定向模式,可以设置follow,error,manual | 'follow' |
| * referrer | String | 可以设置no-referrer,client或URL | 'client' |
| * referrerPolicy | String | 可以设置: no-referrer,no-referrer-when-downgrade,origin,origin-when-cross-origin,unsafe-url | |
| * keepalive | String | 选项可用于允许请求超过页面的生存时间 | |
| * integrity | String | 包括请求的subresource integrity值 | |
| jsonp | String | jsonp入参属性名 | 'callback' |
| jsonpCallback | String | jsonp响应结果的回调函数名 | 默认自动生成函数名 |
| timeout | Number | 设置超时 | |
| headers | Object | 请求头 | |
| transformParams | Function (params,request) | 用于改变URL参数 | |
| paramsSerializer | Function (params,request) | 自定义URL序列化函数 | |
| transformBody | Function (body,request) | 用于改变提交数据 | |
| stringifyBody | Function (body,request) | 自定义转换提交数据的函数 | |
| validateStatus | Function (response) | 自定义校验请求是否成功 | response.status >= 200 && response.status < 300 |
Headers
| 属性 | 类型 | 描述 |
|---|---|---|
| set | Function (name,value) | 添加 |
| append | Function (name,value) | 追加 |
| get | Function (name) | 根据 name 获取 |
| has | Function (name) | 检查 name 是否存在 |
| delete | Function (name) | 根据 name 删除 |
| keys | Function | 以迭代器的形式返回所有 name |
| values | Function | 以迭代器的形式返回所有 value |
| entries | Function | 以迭代器的形式返回所有 [name,value] |
| forEach | Function (callback,context) | 迭代器 |
Response
| 属性 | 类型 | 描述 |
|---|---|---|
| body | ReadableStream | 数据流 |
| bodyUsed | Boolean | 内容是否已被读取 |
| headers | Headers | 响应头 |
| status | Number | 状态码 |
| statusText | String | 状态信息 |
| url | String | 返回请求路径 |
| ok | Boolean | 请求完成还是失败 |
| redirected | Boolean | 是否重定向了 |
| type | String | 类型 |
| clone | Function | 返回一个新的 Response 对象 |
| json | Function | 获取 json 数据 |
| test | Function | 获取 text 数据 |
| blob | Function | 获取 Blob 对象 |
| arrayBuffer | Function | 获取 ArrayBuffer 对象 |
| formData | Function | 获取 FormData 对象 |
全局参数设置
import XEAjax from 'xe-ajax'
XEAjax.setup({
baseURL: 'http://xuliangzhan.com',bodyType: 'json-data',credentials: 'include',log: false,headers: {
'Accept': 'application/json,text/plain,\*/\*;'
},validateStatus (response) {
// 如何需要实现复杂的场景判断,请使用拦截器
return response.status >= 200 && response.status < 300
},transformParams (params,request) {
// 用于在请求发送之前改变URL参数
if (request.method === 'GET') {
params.queryDate = params.queryDate.getTime()
}
return params
},paramsSerializer (params,request) {
// 自定义URL序列化函数,最终拼接在url
return XEUtils.serialize(params)
},
transformBody (body,request) {
// 用于在请求发送之前改变提交数据
body.startTime = body.startDate.getTime()
return body
},stringifyBody (body,request) {
// 自定义格式化提交数据函数
return JSON.stringify(body)
}
})
示例
基本使用
const XEAjax = require('xe-ajax')
XEAjax.ajax({
url: '/api/user/list',method: 'GET',params: {
id: 1
}
})
.then(response => {
if (response.ok) {
// 请求成功
} else {
// 请求失败
}
})
.catch(e => {
// 发生错误
console.log(e.message)
})
fetch 调用,返回一个结果为 Response 对象的 Promise
import XEAjax from 'xe-ajax'
XEAjax.fetch('/api/user/list',{
method: 'POST',body: {
name: 'test'
}
})
.then(response => {
if (response.ok) {
// 请求成功
} else {
// 请求失败
}
}).catch(e => {
// 发生错误
console.log(e.message)
})
// Response Text
XEAjax.fetch('/api/user/list')
.then(response => {
response.text().then(text => {
// text
})
})
// Response JSON
XEAjax.fetch('/api/user/list')
.then(response => {
response.json().then(data => {
// data
})
})
// Response Blob
XEAjax.fetch('/api/user/list')
.then(response => {
response.blob().then(blob => {
// blob
})
})
// Response ArrayBuffer
XEAjax.fetch('/api/user/list')
.then(response => {
response.arrayBuffer().then(arrayBuffer => {
// arrayBuffer
})
})
// Response FormData
XEAjax.fetch('/api/user/list')
.then(response => {
response.formData().then(formData => {
// formData
})
})
// 使用 application/json 方式提交,默认使用 JSON.stringify 序列化数据
let body1 = {
name: 'u111',password: '123456'
}
XEAjax.fetchPost('/api/user/save',body1,{bodyType: 'json-data'})
// 使用 application/x-www-form-urlencoded 方式提交,默认使用 XEAjax.serialize 序列化数据
let body2 = {
name: 'u222',body2,{bodyType: 'form-data'})
// 模拟表单 multipart/form-data 提交
let file = document.querySelector('#myFile').files[0]
let formBody = new FormData()
formBody.append('file',file)
XEAjax.fetchPost('/api/user/save',formBody)
// 查询参数和数据同时提交
XEAjax.fetchPost('/api/user/save',{name: 'u333',password: '123456'},{params: {id: 111}})
XEAjax.fetchGet('/api/user/list')
XEAjax.fetchPut('/api/user/update',{name: 'u222'})
XEAjax.fetchDelete('/api/user/delete/111')
根据请求状态码(成功或失败),返回结果为 Response 数据的 Peomise 对象 (v3.4.0+)
import XEAjax from 'xe-ajax'
// 对请求的响应包含以下信息
// result => {data,status,statusText,headers}
// 根据 validateStatus 状态校验判断完成还是失败
XEAjax.doGet('/api/user/list').then(result => {
// 请求成功 result.data
}).catch(result => {
// 请求失败
})
XEAjax.doGet('/api/user/list/15/1')
XEAjax.doPost('/api/user/save',{name: 'u111'})
XEAjax.doPut('/api/user/update',{name: 'u222'})
XEAjax.doDelete('/api/user/delete/111')
根据请求状态码(成功或失败),返回结果为 json 数据的 Peomise 对象
import XEAjax from 'xe-ajax'
// 根据 validateStatus 状态校验判断完成还是失败,直接可以获取响应结果
XEAjax.getJSON('/api/user/list').then(data => {
// 请求成功 data
}).catch(data => {
// 请求失败
})
XEAjax.getJSON('/api/user/list/15/1')
XEAjax.postJSON('/api/user/save',{name: 'u111'})
XEAjax.putJSON('/api/user/update',{name: 'u222'})
XEAjax.deleteJSON('/api/user/delete/111')
jsonp 调用
import XEAjax from 'xe-ajax'
// 例子1
// 请求路径: http://xuliangzhan.com/api/jsonp/public/message?callback=jsonp_xeajax_1521272815608_1
// 服务端返回结果: jsonp_xeajax_1521272815608_1({message: 'success'})
XEAjax.fetchJsonp('http://xuliangzhan.com/api/jsonp/public/message')
.then(response => {
if (response.ok) {
response.json().then(data => {
// data
})
}
})
// 例子2
// 请求路径: http://xuliangzhan.com/api/jsonp/public/message?cb=jsonp_xeajax_1521272815608_2
// 服务端返回结果: jsonp_xeajax_1521272815608_2({message: 'success'})
XEAjax.doJsonp('http://xuliangzhan.com/api/jsonp/public/message',null,{jsonp: 'cb'})
.then(response => {
// response.data
})
// 例子3
// 请求路径: http://xuliangzhan.com/api/jsonp/public/message?id=222&cb=func
// 服务端返回结果: func({message: 'success'})
XEAjax.jsonp('http://xuliangzhan.com/api/jsonp/public/message',{id: 222},{jsonp: 'cb',jsonpCallback: 'func'})
.then(data => {
// data
})
并发多个请求
import XEAjax from 'xe-ajax'
let iterable1 = []
iterable1.push(XEAjax.fetchGet('/api/user/list'))
iterable1.push(XEAjax.doGet('/api/user/list'))
iterable1.push(XEAjax.postJSON('/api/user/save'),{name: 'n1'})
Promise.all(iterable1).then(datas => {
// 所有异步完成之后执行
}).catch(e => {
// 请求失败时执行
})
// doAll 使用对象参数,用法和 Promise.all 一致
let iterable2 = []
iterable2.push({url: '/api/user/list'})
iterable2.push({url: '/api/user/save',body: {name: 'n1'}},method: 'POST'})
XEAjax.doAll(iterable2)
嵌套请求
import { fetchGet,doGet,getJSON } from 'xe-ajax'
// 相互依赖的嵌套请求
fetchGet('/api/user/info')
.then(response => response.json())
.then(data => fetchGet('/api/user/details',{id: data.id}))
.then(response => {
if (response.ok) {
response.json().then(data => {
// data
})
}
})
doGet('/api/user/info')
.then(result => doGet('/api/user/details',{id: result.data.id}))
.then(result => {
// result.data
})
getJSON('/api/user/info')
.then(data => getJSON('/api/user/details',{id: data.id}))
.then(data => {
// data
})
上传/下载 (v3.4.9+)
参数
| 属性 | 类型 | 描述 |
|---|---|---|
| onUploadProgress | Function (event) | 上传进度监听 |
| onDownloadProgress | Function (event) | 下载进度监听 |
| meanSpeed | Number | 默认0关闭,设置速率为均衡模式,每隔多少毫秒内计算平均速率 |
| fixed | Number | 默认2位数 |
Progress 对象
| 属性 | 类型 | 描述 |
|---|---|---|
| autoCompute | Boolean | 是否自动计算进度,默认true |
| value | Number | 当前进度 % |
| loaded | Object | 已传输大小 {value: 原始大小B,size: 转换后大小,unit: 转换后单位} |
| total | Object | 总大小 {value: 原始大小B,unit: 转换后单位} |
| speed | Object | 传输速度/秒 {value: 原始大小B,unit: 转换后单位} |
| remaining | Number | 剩余时间/秒 |
| time | Number | 时间戳 |
import XEAjax from 'xe-ajax'
// 上传、下载
var file = document.querySelector('#myFile').files[0]
var formBody = new FormData()
formBody.append('file',file)
XEAjax.fetchPost('/api/upload',formBody)
XEAjax.doPost('/api/upload',formBody)
XEAjax.postJSON('/api/upload',formBody)
// 上传进度
// 创建一个进度监听对象
let progress = new XEAjax.Progress()
// 监听上传进度
progress.onUploadProgress = evnt => {
console.log(`进度:${progress.value}% ${progress.loaded.size}${progress.loaded.unit}${progress.total.size}/${progress.total.unit}; 速度:${progress.speed.size}/${progress.speed.unit}秒; 剩余:${progress.remaining}秒`)
}
var file = document.querySelector('#myFile').files[0]
var formBody = new FormData()
formBody.append('file',formBody,{progress})
// 进度:1% 176KB/14.26MB; 速度:1.69MB/秒; 剩余:8秒
// 进度:3% 368KB/14.26MB; 速度:640KB/秒; 剩余:22秒
// 进度:8% 1.16MB/14.26MB; 速度:1.56MB/秒; 剩余:8秒
// ...
// 进度:99% 14.08MB/14.26MB; 速度:119.6KB/秒; 剩余:2秒
// 进度:100% 14.26MB/14.26MB; 速度:114.4KB/秒; 剩余:0秒
// 下载进度
// 创建一个进度监听对象
let progress = new XEAjax.Progress()
// 监听下载进度
progress.onDownloadProgress = evnt => {
console.log(`进度:${progress.value}% ${progress.loaded.size}${progress.loaded.unit}${progress.total.size}/${progress.total.unit}; 速度:${progress.speed.size}/${progress.speed.unit}秒; 剩余:${progress.remaining}秒`)
}
XEAjax.fetchGet('/api/download/file/1',{progress,method: 'GET'})
取消请求 (v3.2.0+)
AbortController 控制器对象
允许控制一个或多个取消指令请求
import XEAjax from 'xe-ajax'
// 创建一个控制器对象
// 如果当前环境支持 AbortController,则使用原生的 AbortController
let controller = new XEAjax.AbortController()
// let controller = new AbortController() // 或者使用原生
// 获取signal
let signal = controller.signal
// 给请求加入控制器 signal
XEAjax.fetchGet('/api/user/list',{id: 1},{signal})
.then(response => {
// 请求成功
}).catch(e => {
// 请求被取消
})
setTimeout(() => {
// 终止请求
controller.abort()
},50)
拦截器 (v3.0+)
拦截器可以对请求之前和请求之后的任何参数以及数据做处理,注意要调用next执行下一步,否则将停止执行。
Request 拦截器
XEAjax.interceptors.request.use(Function([request,next]))
import XEAjax from 'xe-ajax'
// 请求之前拦截器
XEAjax.interceptors.request.use((request,next) => {
// 用于请求的权限拦截、设置请求头、Token 验证、参数等处理...
// 设置参数
request.params.version = 1
// 设置 Token 验证,预防 XSRF/CSRF 攻击
request.headers.set('X-Token',cookie('x-id'))
// 调用 next(),继续执行下一个拦截器
next()
})
Response 拦截器
XEAjax.interceptors.response.use(Function([response,next,request]),Function([response,next]))
import XEAjax from 'xe-ajax'
// 请求完成之后拦截
XEAjax.interceptors.response.use((response,next) => {
// 请求完成之后统一处理,例如校验登录是否失效、消息提示,特殊场景处理等...
// 例子: 判断登录失效跳转
if (response.status === 403) {
router.replace({path: '/login'})
} else {
// 调用 next(),继续执行下一个拦截器
next()
}
},(e,next) => {
// 请求发生错误
// 调用 next(),继续执行下一个拦截器
next()
})
// 请求完成之后重置响应数据
XEAjax.interceptors.response.use((response,next) => {
// 对所有请求返回统一的数据结构
// 格式: {status: 200,statusText: 'OK',body: {},headers: {}}
// 例如,对所有请求结果进行处理,返回统一的结构
response.json().then(data => {
let body = {
status: response.status === 200 ? 'success' : 'error',result: data
}
// 重置响应数据并继续执行下一个拦截器
next({status: response.status,body: body})
})
},next) => {
// 对所有请求错误返回统一的数据结构
let body = {
message: 'error',result: null
}
// 重置响应数据并继续执行下一个拦截器
next({status: 200,body: body})
})
混合函数
./ajax.js
import XEAjax from 'xe-ajax'
export function fn1 () {}
export function fn2 () {}
// ...
./main.js
import XEAjax from 'xe-ajax' import ajaxFns from './ajax' XEAjax.mixin(ajaxFns) XEAjax.fn1() XEAjax.fn2()