promise实现ajax请求,xe-ajax 基于 Promise API 的异步请求函数

最新版本见 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()

总结

如果觉得编程之家网站内容还不错,欢迎将编程之家网站推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
可以使用 Promise 来封装 AJAX 请求。下面是一个示例: ```javascript function request(url, method, data) { return new Promise(function(resolve, reject) { var xhr = new XMLHttpRequest(); xhr.open(method, url, true); xhr.setRequestHeader('Content-Type', 'application/json'); xhr.onload = function() { if (xhr.status >= 200 && xhr.status < 400) { resolve(xhr.response); } else { reject(xhr.statusText); } }; xhr.onerror = function() { reject(xhr.statusText); }; xhr.send(JSON.stringify(data)); }); } ``` 使用示例: ```javascript request('https://api.example.com/data', 'POST', { foo: 'bar' }) .then(function(response) { console.log('请求成功', response); }) .catch(function(error) { console.error('请求失败', error); }); ``` 在封装的 `request` 函数中,我们创建了一个新的 Promise 对象,并在 AJAX 请求的 `onload` 和 `onerror` 事件处理程序中处理成功和失败的情况。如果请求成功,我们调用 `resolve` 方法并传递响应数据,如果请求失败,我们调用 `reject` 方法并传递错误状态信息。 在使用时,我们可以通过链式调用 `.then()` 和 `.catch()` 方法来处理异步请求的结果。`.then()` 方法接收一个回调函数,当请求成功时会调用该函数,并传递响应数据。`.catch()` 方法接收一个回调函数,当请求失败时会调用该函数,并传递错误信息。 这样,我们就可以使用 Promise 来封装 AJAX 请求,并通过链式调用来处理异步请求的结果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值