1. XMLHttpRequest 对象:
1.1 概述:
XMLHttpRequest 对象是一个JavaScript 对象,能够通过 HTTP 协议连接到服务器。Ajax的异步性就是由这个对象的特性获得的。
XMLHttpRequest 向服务器发送一个异步请求,一旦请求被初始化,其余的js代码不需要等待服务器端相应,即异步。
当然,XMLHttpRequest 也可以发送同步请求。
1.2 方法:
open()、send()、abort()、setRequestHeader()
1.2.1 open(method, url,async,username,password):初始化HTTP 请求参数,但不发送:
open(method, url,async,username,password)
参数:
- method: 请求的 HTTP 方法,包括:GET 、POST、HEAD。
- url: 请求的 url 地址。
XMLHttpRequest 受同源策略的约束,不能跨域访问资源。
同源即协议、端口、主机名均相同。- async: 请求是否异步执行。
如果这个参数是 false,请求是同步的,后续对 send() 的调用将阻塞,直到响应完全接收。
如果这个参数是 true 或省略,请求是异步的,且通常需要一个 onreadystatechange 事件句柄,当请求状态改变时会触发这个事件。- username / password: 可选,为 url 所需的授权提供认证资格。如果指定了,它们会覆盖 url 自己指定的任何资格。
1.2.2 send(body):发送 HTTP 请求。
send() 方法用于发送 HTTP 请求。
如果是异步请求,则此方法会在请求发送后立即返回;如果是同步请求,则此方法直到响应到达后才会返回。
send() 方法接受一个可选的参数,其作为请求主体;如果请求方法是 GET 或者 HEAD,则应将请求主体设置为 null。
1.2.3 setRequestHeader(header,value) :设置 HTTP 请求头信息。
注意: 在这之前,你必须确认已经调用了 open() 方法打开了一个 url
header: 规定头的名称; value: 规定头的值
var xhr = new XMLHttpRequest();
xhr.open("POST","/save",true);
xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded");
xhr.send("name=lucy&age=18");
1.2.4 abort() : 取消Http 请求。
1.3 属性
1.3.1 ReadyState 属性值列表
ReadyState 值 | 描述 |
---|---|
0 | 未初始化 Uninitialized —— 已创建 XMLHttpRequest 对象,但还未初始化 |
1 | 创建请求 Open ——调用了 open(),准备好发送一个请求到服务器,但还未发送。 |
2 | 发送请求 Send —— 调用了 send(),请求已发送到 Web 服务器。未接收到响应。 |
3 | 接收响应 Receiving —— 响应头已接收完,响应体开始接收但未完成。 |
4 | 加载 Loaded —— HTTP 响应已经完全接收。 |
1.3.2 onreadystatechange 方法
每次 ReadyState 的值改变时,都会触发 onreadystatechange 事件句柄。
1.3.3 responseType: XMLHttpRequestResponseType
设置该值能够改变响应类型,就是告诉服务器你期望的响应格式
1.3.4 responseText
服务器接收到的响应体(不包括头部),还没有接收到数据的话,就是空字符串。
如果 readyState 小于 3,这个属性就是一个空字符串。
当 readyState 为 3,这个属性返回目前已经接收的响应部分。
如果 readyState 为 4,这个属性保存了完整的响应体。
1.3.5 responseXML
此 responseXML 属性用于当接收到完整的HTTP响应时(readyState为4),将请求的响应描述为 XML, 并作为 Document 对象返回。
1.3.6 status 属性
此 status 为服务器返回的 HTTP 状态码。
仅当 readyState 为 3 或 4 时,这个属性才可用,readyState 小于 3 时读取会引发异常。
常用 HTTP 状态码:
状态码 类别 1XX 信息类状态码 2XX 成功类状态码 3XX 重定向状态码 4XX 客户端错误状态码 5XX 服务端错误状态码 egs:
200 —— 请求成功
301 —— 永久性重定向
302 —— 临时性重定向
401 —— 未经授权
403 —— 禁止访问
404 —— 请求的 url 不存在
500 —— 请求未完成,服务器错误。
1.3.7 statusText 属性
此 statusText 为服务器返回的 HTTP 状态码文本。如:200 —— OK,404 —— Not Found,500 —— Internal Server Error
仅当 readyState 为 3或4时,这个属性才可用,小于3时读取会引发异常。
- 小结:以上为 XMLHttpRequest level1 的相关知识,下面用基于XMLHttpRequest level1 的相关知识创建一个 AJAX 请求来读取文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>ajax 读取 txt </title>
</head>
<body>
<button id="getJson">get</button>
<br>
<br>
<div id="displayJson"></div>
<script>
document.getElementById('getJson').addEventListener('click', clickGet);
function clickGet(){
var xhr = new XMLHttpRequest();
xhr.open('GET', 'simple.txt', true);//创建请求
xhr.send();//发送请求
//onreadystatechange 监控ReadyState 变化。
xhr.onreadystatechange = function(){
if ( xhr.readyState == 4 && xhr.status == 200 ) {
document.getElementById('displayJson').innerHTML = this.responseText;
}
};
}
</script>
</body>
</html>
simple.txt
内容为:there is txt data
则运行 HTML 并点击 get 按钮后页面显示如下:
1.4 XMLHttpRequest Level 2
HTML5 之后的 XMLHttpRequest Level 2 针对 XMLHttpRequest Level 1 进行了改进如下:
- 可以设置HTTP请求的超时时间。
- 可以使用FormData对象管理表单数据。
- 不仅可以发送文本信息,还可以上传文件。
- 可以请求不同域名下的数据(跨域请求)。
- 可以获取服务器端的二进制数据。
- 可以获得数据传输的进度信息。
1.4.1设置超时:timeout & ontimeout
xhr.timeout = 5000; //设置超时时间,过了超时时间,自动停止HTTP请求
xhr.ontimeout = function(e) {
//指定超时的回掉函数
alert('请求超时!');
}
1.4.2 使用 FormData 对象管理表单数据
HTML 5新增了一个 FormData 对象,用于管理表单数据。
- 新建一个 FormData 对象
var form = document.getElementById('myform'); // 获取页面上表单对象
var formData = new FormData(form)
参数 form(可选):
一个HTML 上的 <form> 表单元素,当指定了,这种方式创建的对象会自动将 form 中的表单值也包含进去,包括文件内容也会被编码之后包含进去,未指定则 formData 为一个空的 FormData 对象。
- 添加表单项
var formData = new FormData();
formData.append('username', 'jane');
formData.append('id', 20190823);
- 提交表单,直接传送这个 formData 对象
xhr.send(formData);
1.4.3 上传文件
- 首先使用 type 为 file 的 input 输入框来选中一个文件
<input id="upload" type="file">
- 将选中的文件添加为表单项
var input = document.getElementById("upload");
var formData = new FormData();
formData.append("file", input.files[0]); // file名称与后台接收的名称一致
- 发送表单数据
var xhr = new XMLHttpRequest();
xhr.open('POST', 'http://localhost:3000/uploadFile');//创建请求
xhr.send(formData);//发送请求
1.4.4 跨域资源共享 (CORS)
跨域资源共享(Cross-origin resource sharing,简称 CORS)。
使用"跨域资源共享"的前提,是浏览器必须支持这个功能,而且服务器端必须同意这种"跨域"。如果能够满足上面的条件,则代码的写法与不跨域的请求完全一样。
var xhr = new XMLHttpRequest();
xhr.open('GET', url); //创建请求
xhr.send(); //发送请求
1.4.5 处理二进制数据
- Level 1 的 XMLHttpRequest 对象只能处理文本数据,新版则可以处理其他类型数据。
- 通过设置 ResponseType 来改变响应类型,告诉服务器你期望的响应格式。
把 responseType 设为 blob,表示服务器传回的是二进制对象。 - 接收数据的时候,用浏览器自带的 Blob 对象即可。
var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://localhost:3000/image.png');
xhr.responseType = 'blob';
xhr.send();
xhr.onreadystatechange = function(){
if ( xhr.readyState == 4 && xhr.status == 200 ) {
var blob = new Blob([xhr.response], {type: 'image/png'});
}
};
1.4.6 进度信息
传输数据时,由progress事件返回进度信息,分为上传和下载。
- 下载的progress事件属于XMLHttpRequest对象
- 上传的progress事件属于XMLHttpRequest.upload对象。
//total是需要传输的总字节,loaded是已经传输的字节,如果lengthComputable值不为 true,则 total 为0
function updateProgress(event) {
if (event.lengthComputable) {
var progress = event.loaded / event.total;
}
}
xhr.onprogress = updateProgress;// 下载的progress事件
xhr.upload.onprogress = updateProgress;// 上传的progress事件