ajax
1、ajax
Ajax 即“Asynchronous Javascript And XML”(异步 JavaScript 和 XML),是指一种创建交互式网页应用的网页开发技术。能够无刷新页面而局部改变页面内容。
ajax的核心是 XMLHttpRequst 对象(简称 XHR)。
2、XMLHttpRequest 对象
IE 5 是第一个引入 XHR 的浏览器,在 早期的 IE 中 XHR 是通过 MSXML库中的一个ActiveX对象实现的。
在 IE 中可能会遇到三个不同版本的XHR 对象:"MSXML2.XMLHttp.6.0","MSXML2.XMLHttp.3.0","MSXML2.XMLHttp"。
在 IE7+ 、Firefox、Opera、Chrome、Safari中都支持原生的XHR对象
function createXHR(){ if(typeof XMLHttpRequest != "undefined"){ return new XMLHttpRequest(); }else if(typeof ActiveXObject !="undefined"){ // 兼容ie 7- if(typeof arguments.callee.activeXString != "string"){ var versions = ["MSXML2.XMLHttp.6.0","MSXML2.XMLHttp.3.0","MSXML2.XMLHttp"]; var i,len; for(i=0,len=versions.length;i<len;i++){ try{ new ActiveXObject(versions[i]); arguments.callee.activeXString = versions[i]; break; }catch (e) { //跳过 } } } return new ActiveXObject(arguments.callee.activeXString); }else{ throw new Error("No XHR object available."); } }
3、XHR 的用法
1)xhr.open(method, url, isAsynchronous),参数:请求的方法("post","get"),请求的url,是否是异步请求(true,false,一个可选的布尔参数,默认为true,如果)multipart属性为true则这个必须为true,否则将引发异常。
open()方法是启动一个请求,但并不会发送请求。
2)xhr.send(data):用于发送 HTTP 请求。如果是异步请求(默认为异步请求),则此方法会在请求发送后立即返回;如果是同步请求,则此方法直到响应到达后才会返回。
参数是 作为请求体的数据,如果没有需要通过请求体发送的数据,则为null
void send(); void send(ArrayBufferView data); void send(Blob data); void send(Document data); void send(DOMString? data); void send(FormData data);
收到响应后,响应的数据会自动填充XHR对象的属性:
xhr.responseText:作为响应体返回的文本
xhr.responseXML:如果响应的内容类型是“text/xml”或者“application/xml”,这个属性中将保存包含着响应数据的XML DOM 文档
xhr.status:响应的HTTP状态
xhr.statusText:HTTP状态的说明
3)readyState 属性和 readystatechange 事件:
XHR对象有一个readyState 属性,表示请求/响应过程中的活动阶段,只要 readyState 变化就会触发一次 readystatechange 事件
readyState可取值:
0:未初始化,尚未调用 open()方法
1:启动,已经调用 open()方法,但未调用send() 方法
2:发送,已经调用 send()方法,但未收到响应
3:接受,已经接受到部分响应数据
4:完成,已经接受到全部响应数据,而且数据可用
4)XMLHttpRequest.abort():如果该请求已被发出,XMLHttpRequest.abort() 方法将终止该请求。当一个请求被终止,它的 readyState 属性将被置为0( UNSENT )。
var xhr = createXHR(); xhr.onreadystatechange = function(){ // 必须在xhr.open()之前指定 onreadystatechange 事件处理程序,保证跨浏览器兼容 if(xhr.readyState == 4){ if((xhr.status >=200 && xhr.status <300) || xhr.status == 304){ console.log("success"); console.log(xhr.responseText); }else{ console.log("failed"); console.log(xhr); } } } xhr.open("get","./files/example.txt",true); xhr.send(null);
4、 HTTP 头部信息
每个http请求和响应都会带有相应的头部信息,xhr 对象提供了操作请求头和响应头的方法
浏览器发送ajax请求时可能会带上这些请求头:
Accept:浏览器能够处理的内容类型
Accept-Charset:浏览器能够显示的字符集
Accept-Encoding:浏览器能够处理的压缩编码
Accept-Language:浏览器当前设置的语言
Content-Type:请求发送内容的类型(大小写不敏感,可以不带字符集),"application/json; charset=utf-8","application/x-www-form-urlencoded; charset=utf-8","text/plain; charset=utf-8","text/html; charset=utf-8"
Connection:浏览器与服务器连接类型
Cookie:当前页面的cookie,ajax会自动带上同源的cookie,不会带上不同源的cookie;可以通过前端设置withCredentials为true, 后端设置Header的方式让ajax自动带上不同源的cookie,但是这个属性对同源请求没有任何影响,会被自动忽略。
Host:发请求的页面所在的域
Referer:发请求页面的URI
User-Agent:浏览器用户代理字符串
可以使用 xhr.setRequestHeader("headerKey", "headerValue")设置请求头,需要在 open() 方法之后,send() 之前设置请求头。如果没有使用setRequestHeader()方法设置 Accept 头部信息,则会发送带有* / *的Accept头部。
可以使用 xhr.getResponseHeader("headerKey") 获取响应头
可以使用 xhr.getAllResponseHeaders() 获取所有响应头,多行文本
5、XMLHttpRequest 2级
1)FormData,可以序列化表单或创建于表单格式相同的数据,包括文件。经过它的数据可以使用 XMLHttpRequest.send() 方法送出,如果送出时的编码类型被设为 "multipart/form-data",它会使用和表单一样的格式。
FormData.append():向 FormData 中添加新的属性值,如果FormData 对应的属性值存在则覆盖原值,否则新增一项属性值。
FormData.delete():从 FormData 对象里面删除一个键值对。
FormData.entries():返回一个包含所有键值对的iterator对象。
FormData.get():返回在 FormData 对象中与给定键关联的第一个值。
FormData.getAll():返回一个包含 FormData 对象中与给定键关联的所有值的数组。
FormData.has():返回一个布尔值表明 FormData 对象是否包含某些键。
FormData.keys():返回一个包含所有键的iterator对象。
FormData.set():给 FormData 设置属性值,如果FormData 对应的属性值存在则覆盖原值,否则新增一项属性值。
FormData.values():返回一个包含所有值的iterator对象。
var data = new FormData(); data.append("key","value"); // append() 方法可以添加任意个键值对 data.set("key","value"); data.set("key","value"); var data1 = new FormData(document.forms[0]); // 可以直接使用表单数据穿件formdata data1.append("key","value"); data1.append("key","value"); console.log(data.getAll("key")); console.log(data1.getAll("key"));
2) XMLHttpRequest.timeout,表示该请求的最大请求时间(毫秒),超过该时间请求会自动结束。
在 xhr.open() 方法后且 send() 方法之前设置,默认值为 0,意味着没有超时。
超时并不应该用在一个 document environment (当javascript全局环境是window或iframe时,它被称为文档环境。全局环境是指没有外部环境的环境。) 中的同步 XMLHttpRequests 请求中,否则将会抛出一个 InvalidAccessError 类型的错误
当时间超时,会触发 xhr 对象的 timeout 事件
var xhr = createXHR(); xhr.onreadystatechange = function(){ // 必须在xhr.open()之前指定 onreadystatechange 事件处理程序,保证跨浏览器兼容 if(xhr.readyState == 4){ try { if((xhr.status >=200 && xhr.status <300) || xhr.status == 304){ console.log("success"); console.log(xhr.responseText); }else{ console.log("failed"); console.log(xhr); } } catch (e) { // 假设有 ontimeout 事件处理程序处理 // 当超时请求终止后,readyState 已经是 4 了,会进入 onreadystatechange 事件处理程序,但此时访问 status 属性会导致错误,所使用try-catch } } } xhr.open("get","./files/example.txt",true); xhr.timeout = 1000; // 毫秒 xhr.ontimeout = function(e){ console.log("timeout"); }; xhr.send(null);
3)XMLHttpRequest.overrideMimeType(mimeType):指定一个MIME类型用于替代服务器指定的类型,使服务端响应信息中传输的数据按照该指定MIME类型处理
如果服务器没有指定一个Content-Type 头, XMLHttpRequest 默认MIME类型为"text/xml". 如果接受的数据不是有效的XML,将会出现格”格式不正确“的错误。你能够通过调用 overrideMimeType() 指定各种类型来避免这种情况
xhr = new XMLHttpRequest(); xhr.overrideMimeType("text/plain"); xhr.addEventListener("load", callback, false); xhr.open("get", url); xhr.send(null);
4)XMLHttpRequest 请求的事件
error:请求错误
load:收到完整响应数据(成功),XMLHttpRequest.onload 事件处理程序可以替代 XMLHttpRequest.onreadystatechange,可以不用检查 readyState 属性。
loadend:请求结束(成功,失败,终止)
loadstart:收到响应数据第一个字节
progress:正在接收数据,progress 事件会在浏览器接受新数据期间周期性的触发(用于文件下载进度)。onprogress事件处理程序会接收到一个event对象,该事件对象包含的属性
lengthComputable |
Boolean |
表示进度信息是否可用. 只读. |
loaded |
unsigned long (long) | 已经传输的字节数。这不包括头和其他开销,只包括内容本身。只读。 |
total |
unsigned long (long) | 传输内容的总字节数,如果总字节数未知,这个数字为0 |
5)XMLHttpRequest.upload :返回一个 XMLHttpRequestUpload对象,用来表示上传的进度。
可以被绑定在upload对象上的事件监听器如下:
| 事件 | 相应属性的信息类型 |
onloadstart |
获取开始 |
onprogress |
数据传输进行中,处理程序中的event的属性也包含lengthComputable, loaded, total |
onabort |
获取操作终止 |
onerror |
获取失败 |
onload |
获取成功 |
ontimeout |
获取操作在用户规定的时间内未完成 |
onloadend |
获取完成(不论成功与否) |
<style media="screen"> .parent {width:500px; height:20px; border:1px solid black;} .child {width:0; height:100%; background:green;} </style> <script> window.onload=function (){ let oF=document.getElementById('f1'); let oBtn=document.getElementById('btn1'); oBtn.onclick=function (){ let data=new FormData(); Array.from(oF.files).forEach(file=>{ data.append('f1', file); }); let oAjax=new XMLHttpRequest(); //POST oAjax.open('POST', `http://localhost:8080/api`, true); oAjax.onprogress=function (ev){ console.log(ev); }; oAjax.upload.addEventListener('progress', function (ev){ let oChild=document.getElementsByClassName('child')[0]; oChild.style.width=100*ev.loaded/ev.total+'%'; }, false); oAjax.send(data); }; }; </script> </head> <body> <div class="parent"> <div class="child"> </div> </div> <input type="file" id="f1" multiple /><br> <input type="button" value="提交" id="btn1"> </body>
6)XMLHttpRequest.withCredentials 属性是一个Boolean类型,默认值是false
表示是否该使用类似cookies,authorization headers(头部授权)或者TLS客户端证书这一类资格证书来创建一个跨站点访问控制(cross-site Access-Control)请求。在同一个站点下使用withCredentials属性是无效的。
如果来自其他域的XMLHttpRequest请求在发送之前,未设置withCredentials 为true,那么就不能为那个域设置cookie值。而通过设置withCredentials 为true获得的第三方cookies,将会依旧享受同源策略
7) XMLHttpRequest.responseType
属性 responseType 是一个枚举字符串值,可设置或获取响应中包含的数据类型。
可以是 'arraybuffer', 'blob', 'document', 'json', 'text', 'stream' , 默认是 ‘text’, 如果指定为空字符串,等同于 'text'
https://developer.mozilla.org/zh-CN/docs/Web/API/XMLHttpRequest

浙公网安备 33010602011771号