简单的封装一个 ajax:
- 自动处理参数
- 支持 get 和 post
- 支持取消操作
1. 基于 XMLHttpRequest 封装
XMLHttpRequest 相关信息请参考:MDN–XMLHttpRequest
XMLHttpRequest 对象主要的属性:

1.1 原生 XHR 创建步骤
总共分 5 步:
- 第一步:使用 new XMLHttpRequest() 创建 XHR 实例
- 第二步:使用 xhr.open() 创建一个请求,并初始化相关 http 请求信息
- 设置请求头
- 设置响应 http 状态变化的函数
- 调用 send 方法,发送 http 请求
整体结构:
1 2 3 4 5 6 7 8 9 10
| function myAjax( obj ){ this.url = obj.url || "" this.type = obj.type || "GET" this.data = obj.data ||{} this.success = obj.success || null this.error = obj.error || null this.xhr = new XMLHttpRequest() } myAjax.prototype.send = function(){} myAjax.prototype.abort = function(){}
|
完成结果:
ajax ---- XMLHttpRequest1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| function myAjax( obj ){ this.url = obj.url || "" this.type = obj.type || "GET" this.data = obj.data ||{} this.success = obj.success || null this.error = obj.error || null this.xhr = new XMLHttpRequest() }
myAjax.prototype.send = function(){ let dataArr = [] for( let key in this.data ){ dataArr.push( key + "=" + this.data[key] ) } if( this.type === "GET" || this.type === "get" ){ this.url = this.url + "?" + dataArr.join("&") this.xhr.open( this.type, this.url.replace(/\?$/g, ""), true ) this.xhr.send() } if( this.type === "POST" || this.type === "post" ){ this.xhr.open( this.type, this.url, true ) this.xhr.setRequestHeader( "content-type", "application/x-www-form-urlencoded" ) this.xhr.send( dataArr.join( "&" ) ) } this.xhr.onreadystatechange = () => { if( this.xhr.readyState === 4 && ( this.xhr.status === 200 || this.xhr.status === 304 ) ){ if( this.success && this.success instanceof Function ){ var res = this.xhr.responseText if( typeof res === "string" ){ this.success( JSON.parse( res ) ) } } } } } myAjax.prototype.abort = function(){ console.log( "已经取消请求..." ) this.xhr.abort() }
|
2. 基于 fetch 封装
若果你不知道 fetch 的使用,请参考
- MDN-fetch 文档
- MDN-fetch 使用相关
fetch 第二个参数选项:
- method: 请求使用的方法,如 GET、POST。
- headers: 请求的头信息,形式为 Headers 的对象或包含 ByteString 值的对象字面量。
- body: 请求的 body 信息:可能是一个 Blob、BufferSource、FormData、URLSearchParams 或者 USVString 对象。注意 GET 或 HEAD 方法的请求不能包含 body 信息。
- mode: 请求的模式,如 cors、 no-cors 或者 same-origin。
- credentials: 请求的 credentials,如 omit、same-origin 或者 include。为了在当前域名内自动发送 cookie , 必须提供这个选项, 从 Chrome 50 开始, 这个属性也可以接受 FederatedCredential 实例或是一个 PasswordCredential 实例。
- cache: 请求的 cache 模式: default 、 no-store 、 reload 、 no-cache 、 force-cache 或者 only-if-cached 。
- redirect: 可用的 redirect 模式: follow (自动重定向), error (如果产生重定向将自动终止并且抛出一个错误), 或者 manual (手动处理重定向). 在Chrome中,Chrome 47之前的默认值是 follow,从 Chrome 47开始是 manual。
- referrer: 一个 USVString 可以是 no-referrer、client或一个 URL。默认是 client。
- referrerPolicy: 指定了HTTP头部referer字段的值。可能为以下值之一: no-referrer、 no-referrer-when-downgrade、 origin、 origin-when-cross-origin、 unsafe-url 。
- integrity: 包括请求的 subresource integrity 值
- signal: 用于取消请求
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
| function myFetch( obj ){ this.url = obj.url || "" this.type = obj.type || "GET" this.data = obj.data ||{} this.success = obj.success || null this.error = obj.error || null this.controller = new AbortController() }
myFetch.prototype.send = function(){ let dataArr = [] for( let key in this.data ){ dataArr.push( key + "=" + this.data[key] ) } if( this.type === "GET" || this.type === "get" ){ this.url = this.url + "?" + dataArr.join("&") fetch( this.url.replace(/\?$/g, ""), { mode: "cors", method: "GET", signal: this.controller.signal }).then( res => { return res.json() }).then( resObj => { this.success( resObj ) }) } if( this.type === "POST" || this.type === "post" ){ fetch( this.url, { mode: "cors", headers: { "Content-Type" : "application/x-www-form-urlencoded" }, body: dataArr.join("&"), method: "POST", signal: this.controller.signal }).then( res => { console.log( "新鲜的数据:" ,res ) return res.json() }).then( resObj => { this.success( resObj ) }) } }
myFetch.prototype.abort = function(){ console.log( "取消请求--" ) this.controller.abort() }
|
3. 总结
XMLHttp
使用原生 XMLHttpRequest 创建 ajax 的步骤分 5 步,一定要记住,
- 使用 new XMLHttpRequest() 创建 xhr 实例
- 调用 open 方法初始化请求信息
- 设置 请求头
- 设置请求响应函数
- 调用 send 方法发送请求
4. 关于发送文件和图片
发送文件和图片,需要搭配 FormData
直接将 FormData 作为参数发送即可。
案例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| var formdata = new FormData() var elFile = document.getElementById( "myfile" ) elFile.addEventListener( "change", () => { formdata.append( "file", elFile.files[0] ) sendFile() })
var xhr = new XMLHttpRequest() xhr.open( "post", "http://***/uploadImage" ) xhr.onreadystatechange = function(){ if( xhr.status === 200 && xhr.readyState === 4 ){ console.log( "请求成功----" ) console.log( xhr.response ) } } function sendFile(){ xhr.send( formdata ) }
|
5. 参考材料
MDN–XMLHttpRequest
MDN-fetch 文档
创建ajax过程
AJAX实现步骤,XMLHttpRequest对象的方法