通过 XMLHttpRequest 构造函数原生支持 XHR 对象
let xhr = new XMLHttpRequest();使用 XHR 对象首先要调用 open() 方法,这个方法接收 3 个参数:请求类型、请求URL、请求是否异步的布尔值。
xhr.open("get", "example.php", false);注意: 只能访问同源 URL,否则会抛出安全错误。
发送定义好的请求,必须调用 send() 方法:
send() 方法接收一个参数,是作为请求体发送的数据。如果不需要发送数据,就必须传入 null。
xhr.open("get", "example.php", false); xhr.send(null);收到响应之后, XHR 对象的属性会被填充上数据。
responseText:作为响应体返回的文本。responseXML:如果响应的内容类型是 “text/html” 或 “application/xml”,那就是包含响应数据的 XML DOM 文档。status:响应的 HTTP 状态。statusText:响应的 HTTP 状态描述。XMR 对象又有一个 readyState 属性,表示当前处在请求/响应过程的那个阶段。属性的值:
0:未初始化。尚未调用 open() 方法。1:已打开。已调用 open() 方法,尚未调用 send() 方法。2:已发送。已调用 send() 方法,尚未收到响应。3:接收中。已经收到部分响应。4:完成。已经收到所有响应。 let xhr = new XMLHttpRequest(); xhr.onreadystatechange = function() { if (xhr.readystate == 4) { if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) { console.log(xhr.responseText); } else { console.log("unsuccessful", xhr.status); } } }; xhr.open("get", "example.php", true); xhr.send(null);在收到响应之前如果想取消异步请求,可以调用 abort() 方法。
默认下,XHR 请求会发送以下头部字段
Acceopt:浏览器可以处理的内容类型。Accept-Charset:浏览器可以显示的字符集。Accept-Encoding;浏览器可以处理的压缩编码类型。Accept-Language:浏览器使用的语言。Connection:浏览器与服务器的连接类型。Cookie:页面中设置的 Cookie。Host:发送请求的页面所在的域。Referer:发送请求的页面的 URI。User-Agent:浏览器的用户代理字符串。如果需要发送额外的请求头部。可以使用 setRequestHeader() 方法。接收两个参数:头部字段的名称和值。必须放在 open() 之后,send() 方法之前。
可以使用 getResponseHeader() 方法从 XHR 对象获取响应头部。传入获取头部的名称即可。
获得所有响应头部,可以使用 getAllResponseHeaders() 方法。
需要在 GET 请求的 URL 后面添加查询字符串参数。查询字符串必须正确编码后添加到 URL 后面,再传入 open() 方法。查询字符串中的每个名和值都必须使用 encodeURIComponent() 编码,所有名/值对必须以 “&” 分隔。
xhr.open("get", "example.php?name=xkc&age=20", true);URL 添加查询字符串的方法:
function addURLParam(url, name, value) { url += url.indexOf("?") === -1: "?" : "&"; url += encodeURIComponent(name) + "=" + encodeURIComponent(value); return url; }POST 请求的请求体可以包含非常多的数据。而且数据可以是任意格式。初始化 POST 请求。 open() 方法的第一个参数传入 “post”。
xhr.open("post", "example.php", true);需要再 send() 方法传入要发送的数据。
FormData 类型便于表单序列化。
let data = new FormData(); data.append("name", "xkc");append() 方法接收两个参数:键和值。相对于表单字段名称和字段的值。此外,也可以直接传入一个表单元素。
添加了 timeout 属性。用于表示发送请求后等待多少毫秒,设置一个时间且再该时间过后没有收到响应时,XHR 对象就会触发 timeout 事件。调用 ontimeout 事件处理程序。
let xhr = new XMLHttpRequest(); xhr.onreadystatechange = function() { if (xhr.readystate == 4) { try { if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) { console.log(xhr.responseText); } else { console.log("unsuccessful", xhr.status); } } catch (e) { // 异常处理 console.log(e); } } }; xhr.open("get", "example.php", true); xhr.timeout = 1000; xhr.ontimeout = function () { console.log("没有返回"); } xhr.send(null);timeout 属性设置,如果在时间内没有返回,会触发 ontimeout 事件处理程序,readystate 仍然会返回 4,不过超时之后 status 属性会发生错误。
overrideMimeType() 方法用于重写 XHR 响应的 MIME 类型。
在接收数据期间,progress 事件会反复触发。每次触发时,onprogress 事件处理程序都会收到 event 对象。其 target 属性是 XHR 对象,且有 3 个额外属性:lengthComputable、position 和 totalSize。lengthComputable 是一个布尔值,表示进度信息是否可用;position 是接收到的字符数;totalSize 是响应的 Content-Length 头部定义的总字符数。拥有这些信息,可以给用户提供进度条,
跨域资源共享(CORS)定义了浏览器与服务器如何实现跨域通信。CORS 背后的基本思路是使用自定义的 HTTP 头部允许浏览器和服务器相互了解,以确定请求或响应成功或失败。
跨域 XHR 对象施加额外限制:
不能使用 setRequestHeader() 设置自定义头部。不能发送和接收 cookie。getAllResponseHeaders() 方法始终返回空字符串。CORS 通过一种叫预检请求的服务器验证机制,允许使用自定义头部、以及不同请求体内容类型。包含头部如下:
Origin:与简单请求相同。Access-Control-Request-Method:请求希望使用的方法。Access-Control-Request-Headers:(可选)要使用的逗号分隔的自定义头部列表。服务器会响应中发送头部信息:
Access-Control-Allow-Origin:与简单请求相同。Access-Control-Allow-Methods:允许的方法。Access-Control-Allow-Headers:服务器允许的头部。Access-Control-Max-Age:缓存预检请求的秒数。图片探测是利用 标签实现跨域通信的最早技术。可以跨域加载图片而不必担心限制,可以动态创建图片,然后通过它们的 onload 和 onerror 事件处理程序得知何时收到响应。
let img = new Image(); img.onload = function () { console.log("load"); }; img.src = "https://www.abcd.com/test?name=xkc";JSONP 格式包含两个部分:回调和数据。回调是在页面接收到响应之后应该调用的函数,通常回调函数的名称是通过请求来动态指定的。数据就是作为参数传入回调函数的 JSON 数据。
http://abcd.com/json/?callback=handleResponse
这个例子中的回调函数名称指定为 handleResponse()。
JSONP 调用是通过动态创建
function handleResponse(response) { console.log(response.name, response.age); } let script = document.createElement("script"); script,src = "http://abcd.com/json/?callback=handleResponse"; document.body.insertBefore(script, document.body,firstChild);缺点:
JSONP 是从不同的域中拉取可执行代码。不安全,一定要保证可信度。不好确定 JSONP 请求是否失败。