前提
观看该文章之前,你需要具备的知识有:
- Promise的使用,包含 Promise#then,Promise#catch,Promise.resolve,Promise.reject;
- XHR 的使用,包含低版本浏览器实现的兼容操作等;
- 函数的使用,包含回调,传递,执行等;
XMLHttpRequest 实现请求函数封装
首先, XMLHttpRequest (XHR)对象可以与服务器交互。你可以从URL获取数据,而无需让整个的页面刷新。这允许网页在不影响用户的操作的情况下更新页面的局部内容。在 Ajax 编程中 XMLHttpRequest 被大量使用。
XMLHttpRequest()
该构造函数用于初始化一个 XMLHttpRequest
对象。在调用下列任何其他方法之前,必须先调用该构造函数,或通过其他方式间接得到一个 XMLHttpRequest
对象。
XMLHttpRequest.onreadystatechange
当 readyState 属性发生变化时调用的 EventHandler
。
XMLHttpRequest.responseText
一个用于定义响应类型的枚举值(enumerated value)。
XMLHttpRequest.readyState
只读
返回 一个无符号短整型(unsigned short)数字,代表请求的状态码。
一个用于定义响应类型的枚举值(enumerated value),可选值:
值 |
描述 |
"" |
将 responseType 设为空字符串与设置为"text"相同, 是默认类型 (实际上是 DOMString)。 |
"arraybuffer" |
response 是一个包含二进制数据的 JavaScript ArrayBuffer 。 |
"blob" |
response 是一个包含二进制数据的 Blob 对象 。 |
"document" |
response 是一个 HTML Document 或 XML XMLDocument ,这取决于接收到的数据的 MIME 类型。请参阅 HTML in XMLHttpRequest 以了解使用 XHR 获取 HTML 内容的更多信息。 |
"json" |
response 是一个 JavaScript 对象。这个对象是通过将接收到的数据类型视为 JSON 解析得到的。 |
"text" |
response 是包含在 DOMString 对象中的文本。 |
"moz-chunked-arraybuffer" |
与"arraybuffer"相似,但是数据会被接收到一个流中。使用此响应类型时,响应中的值仅在 progress 事件的处理程序中可用,并且只包含上一次响应 progress 事件以后收到的数据,而不是自请求发送以来收到的所有数据。在 progress 事件处理时访问 response 将返回到目前为止收到的数据。在 progress 事件处理程序之外访问, response的值会始终为 null 。 |
"ms-stream" |
response 是下载流的一部分;此响应类型仅允许下载请求,并且仅受Internet Explorer支持。 |
XMLHttpRequest.response
只读
返回一个 ArrayBuffer
、Blob
、Document
,或 DOMString
,具体是哪种类型取决于 XMLHttpRequest.responseType
的值。其中包含整个响应体(response body)。
XMLHttpRequest.responseText
只读
返回一个 DOMString
,该 DOMString
包含对请求的响应,如果请求未成功或尚未发送,则返回 null
。
XMLHttpRequest.responseURL
只读
返回响应的序列化(serialized)URL,如果该 URL 为空,则返回空字符串。
返回一个无符号短整型(unsigned short)数字,代表请求的响应状态。
XMLHttpRequest.statusText
只读
返回一个 DOMString
,其中包含 HTTP 服务器返回的响应状态。与 XMLHTTPRequest.status
不同的是,它包含完整的响应状态文本(例如,"200 OK
")。
// 序列化参数functionserialize(data){ if(!data) return''; varpairs= []; for(varnameindata){ if(!data.hasOwnProperty(name)) continue; if(typeofdata[name] ==='function') continue; varvalue=data[name].toString(); name=encodeURIComponent(name); value=encodeURIComponent(value); pairs.push(name+'='+value); } returnpairs.join('&'); } // 创 Ajax 请求对象,兼容ie8,ie9functionXHR(){ varxObj; if (window.XMLHttpRequest) { xObj=newXMLHttpRequest(); } elseif (window.ActiveXObjext) { xObj=newActiveXObject(); } returnxObj; } // get封装functionget(url,header,options,callback){ varxhr=XHR(); xhr.onload=function(){ callback(xhr.responseText); } xhr.onerror=function(callback){ callback(xhr.status); } url=url+'?'+serialize(options); xhr.open('get',url,true); for(variinheader){ xhr.setRequestHeader(i,header[i]); } xhr.send(null); } // get请求startvarmethod='GET', url='http://ali-weather.showapi.com/hour24', header= { 'Content-Type': 'application/json', 'Authorization': 'APPCODE d27f87315ec34adf88a4437769a09b76' }, data= { area: '广州' }; get(url,header,data,function(params){ console.log(JSON.parse(params)); }) // post封装functionpost(url,header,options,callback){ varxhr=createAjax(); xhr.onload=function(){ callback(xhr.responseText); }; xhr.onerror=function(callback){ console.log(xhr.status); }; xhr.open('post', url, true); for(variinheader){ xhr.setRequestHeader(i,header[i]); } xhr.send(serialize(data)); } varmethod='POST', url='http://ali-weather.showapi.com/hour24', header= { 'Content-Type': 'application/json', 'Authorization': 'APPCODE d27f87315ec34adf88a4437769a09b76' }, data= { area: '广州' }; post(url,header,data,function(params){ console.log(JSON.parse(params)); })
Promise 封装
// 序列化参数functionserialize(data){ if(!data) return''; varpairs= []; for(varnameindata){ if(!data.hasOwnProperty(name)) continue; if(typeofdata[name] ==='function') continue; varvalue=data[name].toString(); name=encodeURIComponent(name); value=encodeURIComponent(value); pairs.push(name+'='+value); } returnpairs.join('&'); } // 创 Ajax 请求对象,兼容ie8,ie9functionXHR(){ varxObj; if (window.XMLHttpRequest) { xObj=newXMLHttpRequest(); } elseif (window.ActiveXObjext) { xObj=newActiveXObject(); } returnxObj; } // get封装functionajax(url, data, method='GET', responseType='json', header){ returnnewPromise((resolve,reject)=>{ varxhr=XHR(); varparams=nullxhr.onreadystatechange=handler; // 请求状态变化时的回调处理函数if(method.toUpperCase() ==='GET'){ url=url+'?'+serialize(data); }elseif(method,toUpperCase() ==='POST'){ params=serialize(data) } xhr.open(method,url,true); for(variinheader){ xhr.setRequestHeader(i,header[i]); } !xhr['Content-Type'] && (xhr['Content-Type'] ='application/json') xhr.responseType=responseTypexhr.send(params); functionhandler(){ if(this.readyState!==4){ return ; } if(this.status===200){ resolve(this.response) }else { reject(newError(this.statusText)); } } }) } // get请求startvarmethod='GET', url='http://songfens.club:3000/goods/list', header= { 'Content-Type': 'application/json', 'Accept':'application/json' }, data= { page:1, pageSize:8, sort:1, priceLevel:'all' }; ajax(url, data, method, responseType='json', header).then((res)=>{ console.log(res); }).catch(err=>{ console.warn(err) })