一、INTRO
AJAX即“Asynchronous Javascript And XML”
一、Ajax的原生初级
1.1 Ajax对象创建:var xhr= new XMLHttpRequest();
1.2 请求首行:xhr.open('post/get', 'url',true/false); 第三个参数为是否异步,默认是异步(true)
1.3 数据发送:xhr.send(data); 如为get请求发送null
1.4 设置请求头:xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); 如果send内容为urlencoded格式(“a=1&b=2”),请参照该样式设置。
1.5 检查是否请求完毕:readyState属性
只要readyState 触发就会触发readystatechange事件!
readyState有5个值:0~4,分别表示:未初始化、启动、发送、接受、完成。
xhr.onreadystatechange = function(){ if (xhr.readyState == 4){ if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){ //可以在完成后调用xhr.status,查看状态码 alert(xhr.responseText); //xhr.responseText即是返回的数据 } else { alert("Request was unsuccessful: " + xhr.status); } } };
1.6 初级示例
var xhr = XMLHttpRequest(); xhr.onreadystatechange = function(){ if (xhr.readyState == 4){ if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){ alert(xhr.responseText); } else { alert("Request was unsuccessful: " + xhr.status); } } }; xhr.open("post/get", "url", true); xhr.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); xhr.send("a=1&b=2");
二、XMLHttpRequest 中级
2.1 formData:
var data = new FormData(); 用法:data.append("key","value"); data.append(document.forms[0]); data.append(inputdom); 或者直接 var data = new FormData(document.forms[0]);
最后:xhr.send(FormData对象);
FormData主要服务于表单上传:
如表单中存在文件上传,原生js中可以直接将文件放入FormData,无需任何特殊处理!
var xhr = new XMLHttpRequest(); xhr.open('post', 'url'); // 设置请求头(get请求可以省略,post不发送数据也可以省略) // 如果使用的时 formData可以不写请求头写了无法正常上传文件 // xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded"); xhr.onload = function () { console.log(xhr.responseText); } // XHR2.0新增 上传进度监控 xhr.upload.onprogress = function (event) { // console.log(event); var percent = event.loaded / event.total * 100 + '%'; console.log(percent); var data = new FormData(document.querySelector('form')); xhr.send(data);
2.2 进度事件
1. xhr引入了load事件,用以替代 readystatechange 事件。响应接收完毕后将触发 load 事件,因此也就没有必要去检查 ready State 属性了。而 onload 事件处理程序会接收到一个 event 对象,其 target 属性就指向 XHR 对象实例。
1 xhr.onload = function(){ 2 if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){ 3 alert(xhr.responseText); 4 } else { 5 alert("Request was unsuccessful: " + xhr.status); 6 } 7 };
var xhr = new XMLHttpRequest(); xhr.onload = function(){ if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304){ alert(xhr.responseText); } else { alert("Request was unsuccessful: " + xhr.status); } }; xhr.open("get", "altevents.php", true); xhr.send(null);
2. progress
onprogress 事件处理程序会接收到一个 event 对象,其 target 属性是 XHR 对象,并包含着三个额外的属性:lengthComputable、loaded(position) 和 total(totalSize)。其中,lengthComputable
是一个表示进度信息是否可用的布尔值,position 表示已经接收的字节数,totalSize 表示根据Content-Length 响应头部确定的预期字节数。
xhr.onprogress = function(event){ if (event.length Computable){ console.log("Received " + event.position + " of " + event.totalSize +" bytes"); } }
3. upload事件
XHR2也给出了用于监控HTTP请求上传的事件。在实现这些特性的浏览器中,XMLHttpRequest对象将有upload属性。upload属性值是一个对象,它定义了addEventListener()方法和整个progress事件集合,比如onprogress和onload(但upload对象没有定义onreadystatechange属性,upload仅能触发新的事件类型)。通常设置XHR.onprogress监控下载进度,设置XHR.upload.onprogress监控上传进度。
1 xhr.upload.onprogress = function (event) { 2 // console.log(event); 3 var percent = event.loaded / event.total * 100 + '%'; 4 console.log(percent); 5 // 设置 进度条内部step的宽度 6 document.querySelector('.step').style.width = percent; 7 }
4. 其他事件:
HTTP请求无法完成有3种情况,对应3种事件。如果请求超时,会触发timeout事件。如果请求中止,会触发abort事件。最后,像太多重定向这样的网络错误会阻止请求完成,但这些情况发生时会触发error事件。
1 var xhr = new XMLHttpRequest(); 2 btn.onclick = function(){ 3 xhr.abort(); 4 }; 5 xhr.ontimeout = function(){ 6 console.log('The request timed out.'); 7 } 8 xhr.timeout = 100; 9 xhr.onabort = function(){ 10 console.log("The transfer has been canceled by the user."); 11 } 12 xhr.onerror = function(){ 13 console.log("An error occurred while transferring the file."); 14 } 15 xhr.onloadend = function(){ 16 console.log("请求结束"); 17 }
三、Fetch原生ajax新形态
XMLHttpRequest实在是太难写了,你可能都无法理解为什么XML是全大写,而HTTP同样是缩写为什么只有首字母大写?还好es2015给我们提供了新api——window.Fetch
3.1 request
fetch('/some/url', { method: 'get' })
请求参数:
method
- 支持GET
,POST
,PUT
,DELETE
,HEAD
url
- 请求的 URL (必须)headers
- 对应的Headers
对象referrer
- 请求的 referrer 信息mode
- 可以设置cors
,no-cors
,same-origin
- same-origin 如果一个请求是跨域的,返回一个error,这样确保所有的请求遵守同源策略
- no-cores 模式允许来自CDN的脚本、其他域的图片和其他一些跨域资源,但是首先有个前提条件,就是请求的method只能是"HEAD","GET"或者"POST"。avaScript不能访问Response中的任何属性
- cors 通常用作跨域请求来从第三方提供的API获取数据。这个模式遵守CORS协议。response的body信息可读
credentials
- 设置 cookies 是否随请求一起发送.(对于有set-cookie的返回请求,request一定带着这个属性!)
-
omit
: Never send cookies. -
same-origin
: Send user credentials (cookies, basic http auth, etc..) if the URL is on the same origin as the calling script. -
include
: Always send user credentials (cookies, basic http auth, etc..), even for cross-origin calls.
-
redirect
-follow
,error
,manual
integrity
- subresource 完整性值(integrity value)cache
- 设置 cache 模式 (default
,reload
,no-cache
)- body - 请求体
var request = new Request('/users.json', { method: 'POST', mode: 'cors', redirect: 'follow', headers: new Headers({ 'Content-Type': 'text/plain' }) }); fetch(request)
3.2 请求头
// 初始化 let headers = new Headers(); headers.append('Content-Type', 'text/plain'); 或者 let headers = new Headers({'Content-Type': 'text/plain'}) // 判断(has), 获取(get), 以及修改(set)请求头的值 headers.has('Content-Type'); // true headers.get('Content-Type'); // "text/plain" headers.set('Content-Type', 'application/json'); // 删除某条请求头信息(a header) headers.delete('X-My-Custom-Header');//甚至可以替换var postReq = new Request(oldreq, {method: 'POST'});
fetch('/some/url', { method: 'get', headers: headers })
Headers对象有一个特殊的guard属性: 具体参见文档
- "none": 默认的
- "request": 从Request中获得的Headers只读。
- "request-no-cors":从不同域的Request中获得的Headers只读。
- "response": 从Response获得的Headers只读。
- "immutable" 在ServiceWorkers中最常用的,所有的Headers都只读。
3.3 response
① response参数 —— 在前端不需要自行设置
type
- 类型,支持:basic
,cors
url
useFinalURL
- Boolean 值, 代表url
是否是最终 URLstatus
- 状态码 (例如:200
,404
, 等等)ok
- Boolean值,代表成功响应(status 值在 200-299 之间)statusText
- 状态值(例如:OK
)headers
- 与响应相关联的 Headers 对象.- bodyUsed - request或者response中的body信息只能被用一次,以这个bodyUsed作为表示,true-代表被用过了。
② response方法
clone()
- 创建一个新的 Response 克隆对象。如果有多次 调用body的需求可用clone方法,复制然后调用body信息error()
- 返回一个新的,与网络错误相关的 Response 对象.redirect()
- 重定向,使用新的 URL 创建新的 response 对象..arrayBuffer()
- Returns a promise that resolves with an ArrayBuffer.blob()
- 返回一个 promise, resolves 是一个 Blob.formData()
- 返回一个 promise, resolves 是一个 FormData 对象.json()
- 返回一个 promise, resolves 是一个 JSON 对象.text()
- 返回一个 promise, resolves 是一个 USVString (text).
③简单应用
fetch("/data.json").then(function(res) { if (res.ok) { res.json().then(function(data) { console.log(data.entries); }); } else { console.log("Looks like the response wasn't perfect, got status", res.status); } }, function(e) { console.log("Fetch failed!", e); });
3.4 用法
①处理json
fetch(requestObj).then(function(response) { return response.json(); }) // 这里可以直接利用这个response.json()数据,也可以return利用promise中then的传递继续处理: .then(function(json_data) { console.log(json_data); });
② 处理一般数据
fetch(requestObj) .then(function(response) {return response.text()}).then(function(res){console.log(res)})
③ 上传formdata
fetch(url, { method: 'post', body: new FormData(document.getElementById('comment-form')) }).then(function(request){return response.text()}).then(function(res){console.log(res)})
④ 上传json
fetch(url, { method: 'post', body: JSON.stringify({ email: value answer: value }) }).then(function(request){return response.text()}).then(function(res){console.log(res)})
⑤普通post请求
fetch("http://www.example.org/submit.php", { method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded" }, body: "firstName=Nikhil&favColor=blue&password=easytoguess" }).then(res=> { if (res.ok) { alert("Perfect! Your settings are saved."); } else if (res.status == 401) { alert("Oops! You are not authorized."); } }, e=> { alert("Error submitting form!"); }); //第二个参数相当于catch()
来源:https://www.cnblogs.com/yxi-liu/p/ajax.html