内容提要
XMLHttpRequest (XHR)对象是一个基于浏览器层面的API,可以通过JavaScript 实 现 数 据 传 输。 为后来的AJAX提供了革命性的技术支持;
主要 用于与服务器交互
XMLHttpRequest 文章中统一用简称(XHR)代替
主要讨论
XHR 怎么使用?
通过js 怎么实现数据传输?
既然是基于浏览器的API,浏览器为我们做了那些事情?
传输过程的安全机制是怎么产生的?
跨域(CORS)是怎么产生的?如何访问跨域?
XHR 用法
XHR 对象的使用和普通的对象一毛一样,也是需要new的,然后在调用对象里面的方法。但是又有自己的小心思:
let xhr = new XMLHttpRequest();
xhr.open('get','/example.do',false);
这里调用了open 方法,但是并不会向服务器发送请求,可以简单理解为启动一个备发送
这个就和普通对象不一样了。还需要send()方法组合才能真正的发送到服务器
open 语法
两个必传 三个可选
xhr.open(method, url, async, user, password);
method | 必传 要使用的HTTP方法,比如「GET」、「POST」、「PUT」、「DELETE」、等 |
---|---|
url | 必传 发送请求的URL (相对 |
async | 可选 默认值为true 是否是异步请求 |
user | 可选 默认值为null 用户名用于认证用途 |
password | 可选 默认值为null 密码用于认证用途 |
通常在项目中我们只是关心前面两个参数或者三个参数
要使xhr.open() 成功请求到服务器,还需要send方法,以上案例要请求成功还需要加上如下操作
xhr.send(null);
send 方法接受一个可选的参数,其作为请求主体;如果请求方法是 GET 或者 HEAD,则应将请求主体设置为 null 如上面的 方法是get,如果是post 就传入相关的数据
向服务器发送请求的目的是期待获取到数据为我所用,那么数据返回到哪里了?
关于数据去哪里了。首先需要介绍XHR的两个属性嘉宾,readyState 和status
readyState 用来标识当前XMLHttpRequest对象处于什么状态。 这些状态值记录者XHR当前的情况,一共有5中状态来描述
readyState 状态值 | 描述 |
---|---|
0 | 此时,已经创建了一个XMLHttpRequest对象 |
1 | 此时,已经调用了XMLHttpRequest对象的open方法 |
2 | 此时,已经通过send方法把一个请求发送到服务器端,但是还没有收到一个响应 |
3 | 此时,已经接收到HTTP响应头部信息,但是消息体部分还没有完全接收到 |
4 | 此时,已经完成了HTTP响应的接收 |
status 是XMLHttpRequest对象的一个属性,但是它表示响应的HTTP状态码 无论是否请求成功,服务器都会返回的HTTP头信息代码,有5大类的状态码返回
status 类 | 描述 |
---|---|
1xx | 服务器收到请求,需要继续处理 |
2xx | 处理成功响应类,表示动作被成功接收、理解和接受 |
3xx | 重定向响应类,为了完成指定的动作,必须接受进一步处理 |
4xx | 客户端错误,客户请求包含语法错误或者是不能正确执行 |
5xx | 服务端错误,服务器不能正确执行一个正确的请求 |
几个常用的状态码
status状态码 | |
---|---|
200 | 请求成功 表示请求所希望的响应头或数据体将随此响应返回 |
302 | 表示临时重定向,请求将包含一个新的URL地址,客户端将对新的地址进行GET请求 |
304 | 标示请求的资源没有修改,可以直接用浏览器的缓存数据 |
404 | 表示客户端请求的资源不存在 |
500 | 表示服务器遇到了一个未曾预料的情况,导致了它无法完成响应 服务器产生内部错误 |
而 readyState 的状态值每变化一次都会触发一个XHR对象的事件onreadystatechange,从而更友好的获取到想要到数据
总的来说只要服务器接受到请求,就会自动去填充XHR相关属性,作为js到使用者接受即可
填充的相关XHR属性 | 说明 |
---|---|
responseText | 作为响应主体被返回的文本,如果请求未成功或尚未发送,则返回 null。 |
responseXML | XML 形式的响应数据,如果请求未成功或尚未发送,则返回 null |
其他的不列举
为什么可以直接获取到数据还要去了解 readyState 和status 以及onreadystatechange 方法呢?
因为我们只关心对开发有用的数据 比如readyState 通常情况我们只用去关心 4这个状态值,status 关心200 和304 就可以。在来通过onreadystatechange 获取最终的的数据就是,我们需要的数据,过滤去其他没用的,这样一套完整的请求就出来了。
let xhr = new XMLHttpRequest();
xhr.open('get','/example.do',true);
// 监听readyState 的值
xhr.onreadystatechange=function(){
// xhr 的状态值
if(xhr.readyState === 4){
// http 返回状态码
if(xhr.status === 200 || xhr.status === 304){
// 等到我们期待的文本结果
console.log(xhr.responseText)