XML是过时的web规范产物,可以仅作了解,实际开发中应尽可能使用fetch()等
const xhr = new XMLHttpRequest();
const xhr = new XMLHttpRequest();
// 1.打开一个请求
xhr.open(method, url, isAsync); // 请求方法,请求路径,是否同步请求
// xhr.open('get', 'example.php', false);
// 2.发送一个请求
xhr.send(data); // 如果不需要发送数据,就send(null);
// 3.同步请求会在服务器响应后再继续执行,收到请求后,xhr对象上会填充如下属性
/**
responseText: 作为响应体的文本
responseXML: 如果相应内容为“text/html”或者“application/xml”, 则包含响应数据的XML DOM文档
status: 响应HTTP的状态
statusText: 响应HTTP的描述。
*/
同步请求:
/******** demo ************/
xhr.open("get", "example.txt", false);
xhr.send(null);
if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {alert(xhr.responseText);
} else {alert("Request was unsuccessful: " + xhr.status);
}
异步请求:监听XMR对象上的readyState属性值的变化
readStaty属性值 | 说明 |
---|---|
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) {alert(xhr.responseText);} else {alert("Request was unsuccessful: " + xhr.status);}}
};
xhr.open("get", "example.txt", true);
xhr.send(null); // 如果想要取消异步请求,可以调用xhr.abort();
XHR请求头部字段
字段 | 含义 |
---|---|
Accept | 浏览器可以处理的内容类型 |
Accept-Charset | 浏览器可以现实的字符集 |
Accept-Encoding | 浏览器可以处理的压缩编码类型 |
Accept-Language | 浏览器使用的语言 |
Connection | 浏览器和服务器连接的类型 |
Cookie | cookie数据 |
Host | 发送请求的页面所在的域 |
Referer | 发送请求的页面的url |
User-Agent | 浏览器的用户代理字符串 |
可以通过setRequestHeader(key, val)
自定义请求头字段,必须在open()
调用之后,send()
调用之前调用。
获取响应头部的方法getResponseHeader(key)
和getAllResponseHeader()
发送 GET 请求最常见的一个错误是查询字符串格式不对。查询字符串中的每个名和值都必须使用encodeURIComponent()编码
POST 请求相比 GET 请求要占用更多资源。从性能方面说,发送相同数量的数据,
GET 请求比 POST 请求要快两倍
xhr.send(formdata); // 不需要显示地设置头部
let data = new FormData();
data.append('name', 'coder');
xhr对象上添加了timeout属性,用于设置超时时间
let xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {if (xhr.readyState == 4) {try {if ((xhr.status >= 200 && xhr.status < 300) || xhr.status == 304) {alert(xhr.responseText);} else {alert("Request was unsuccessful: " + xhr.status);}} catch (ex) {// 假设由 ontimeout 处理}}
};
xhr.open("get", "timeout.php", true);
xhr.timeout = 1000; // 设置 1 秒超时
xhr.ontimeout = function() {alert("Request did not return in a second.");
};
xhr.send(null);
用于重写XHR响应的MIME类型,必须在send()
之前调用
let xhr = new XMLHttpRequest();
xhr.open("get", "text.php", true);
xhr.overrideMimeType("text/xml");
xhr.send(null);
这些事件最初只针对xhr,现在也推广到其他api了
事件 | 含义 |
---|---|
loadstart | 在接收到响应的第一个字节时触发 |
progress | 在接受响应期间反复触发 |
error | 在请求出错时触发 |
abort | 调用abort()时 |
load | 在成功接受完响应时触发 |
loadend | 在通信完成时触发,且在error、abort、load之后 |
firefox在实现xhr时,增加load事件代替readystatechange事件, event.target=== xhr
let 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);
onprogress事件接收到event对象,其target属性为XHR对象,且包含三个额外属性
lengthComputable: 布尔值,表示进度信息是否可用
position:接收到的字节数
totalSize: 响应的Content-Length头部定义的总字节数
必须在调用open()之前添加onprogress事件
let xhr = new XMLHttpRequest();
xhr.onload = function(event) {if ((xhr.status >= 200 && xhr.status < 300) ||xhr.status == 304) {alert(xhr.responseText);} else {alert("Request was unsuccessful: " + xhr.status);}
};
xhr.onprogress = function(event) {let divStatus = document.getElementById("status");if (event.lengthComputable) {divStatus.innerHTML = "Received " + event.position + " of " + event.totalSize + " bytes";}
};
xhr.open("get", "altevents.php", true);
xhr.send(null);
受同源策略限制,XHR只能访问与发起请求的页面同一个域内的资源。
对于简单请求,请求头部有个Origin
字段,包含请求页面的源,如果服务器决定响应请求,响应头应包含Access-Control-Allow-Origin
(此行为会被自动触发)
跨域XHR对象还有一些额外的限制
setRequestHeader()
自定义头部字段请求头字段
字段 | 含义 |
---|---|
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 | 缓存预检请求的秒数 |
默认情况下,跨域请求不会提供凭据
可以通过将xhr对象的withCredentials
属性设为true来表明会发送凭据请求。此时响应头中应当包含Access-Control-Allow-Credentials:true
任何页面都可以跨域加载图片,而不用担心限制,
缺点是:只能发送get请求,无法获取服务器的相应数据
let img = new Image();
img.onload = img.onerror = function() {alert("Done!");
};
img.src = "http://www.example.com/test?name=Nicholas";
JSONP格式包括回调
和数据
两部分,其调用是通过动态创建