AJAX
什么是AJAX?
AJAX全拼Asynchronous JavaScript and XML,意为异步JavaScript和XML,用于解决用户向后台发起请求后不需重新加载整个页面,只要将获取的数据插入到指定位置即可,提高了应用程序的执行能力
AJAX核心
AJAX核心对象是XMLHttpRequest,通过这个对象中的方法可以实现异步通信1
2
3
4
5
6
7
8
9
10var xhr = new XMLHttpRequest();
xhr.open("GET", "http://www.xxxx.com/api", false); //xhr.open接收3个参数(请求方式, 请求URL, 是否异步)
xhr.send(null);
if((xhr.status >= 200 && xhr.status < 300) || xhr.status === 304) {
console.log(xhr.responseText);
}
else {
console.log(xhr.status);
}
在IE7之前使用ActiveXObject对象实现相同的功能:var xhr = new ActiveXObject(不同版本); //3个版本:"MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0", "MSXML2.XMLHttp"
兼容IE7之前版本的AJAX写法1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22function createXHR() {
if(typeof XMLHttpRequest != "undefined") {
return new XMLHttpRequest();
} else if(typeof ActiveXObject != "undefined") {
if(typeof arguments.callee.activeXString != 'string') {
var versions = ["MSXML2.XMLHttp.6.0", "MSXML2.XMLHttp.3.0", "MSXML2.XMLHttp"],i,len;
for(i = 0, len = versions.length; i < len; i++) {
try {
new ActiveXObject(versions[i]);
arguments.callee.activeXString = versions[i];
break;
} catch (ex) {
}
}
}
return new ActiveXObject(arguments.callee.activeXString);
} else {
throw new Error("No XHR object available.");
}
}
在XHR中属性readyState代表请求/响应的活动阶段,有4个活动阶段:
- 0:未初始化(还未调用open方法)
- 1:启动(调用了open,还未调用send方法)
- 2:发送(调用了send,但未响应)
- 3:接收(收到部分响应数据)
- 4:完成(响应数据接收完毕)
若想取消异步请求,可以使用xhr.abort()
AJAX进度事件
目前的W3C草案共有6个事件,前五个已被大部分浏览器支持:
- loadstart: 在接收到响应数据的第一个字节时触发
- progress: 在接收响应期间持续不断触发
- error: 请求发生错误时触发
- abort: 因为调用abort()方法后触发
- load: 接收到完整的响应数据时触发
- loadend: 在通信完成或者error、abort、load事件后触发
AJAX流程
通过AJAX获取数据的过程中可能会有一段空白区,而在这段空白区之间JavaScript将继续执行,接收到服务器的响应后第一件事是检测状态,如果状态正确就可以取出数据更新局部页面
![此处输入图片的描述][1]
AJAX相关API
启动一个请求:xhr.open(方法, URL, 是否异步)
发送数据给服务器:xhr.send(数据)
监听readystate变化,需要在open()方法前指定:xhr.onreadystatechange: function() {}
中止异步请求:xhr.abort()
设置请求头部,需要在open()方法后send()方法前:xhr.setRequestHeader(名称, 值)
获取指定名称的响应头部:xhr.getResponseHeader(名称)
获取所有响应信息:xhr.getAllResponseHeaders()
设置超时时间:xhr.timeout = 毫秒
请求超时后触发该函数:xhr.ontimeout = function() {}
重写响应的MIME类型:xhr.overrideMimeType(类型) //xhr.overrideMimeType("text/xml")
[1]: https://raw.githubusercontent.com/jacklincao/myImages/master/hexoImages/2018/03/02/Ajax1.jpg
跨域
什么是CORS?
CORS: Cross-Origin Resource Sharing(跨源域资源共享),用一些技术实现请求非同源域下的资源
基本思想:让浏览器与服务器进行沟通,判断能否成功请求,请求时浏览器会在请求头部加上Origin,服务器收到后对此做验证,若同意请求,服务器发回的响应将包含Access-Control-Allow-Origin(这个头部返回的内容要与发送的源信息一致或”*”),若无此字段浏览器将报错
默认行为:跨域请求不发送cookie、HTTP认证等,通过设置withCredentials为true,这样浏览器就会发送cookie等信息,同时服务器的响应头部需要有:Access-Control-Allow-Credentials: true,否则浏览器将报错
Preflighted Requests:CORS可通过该机制获取服务器是否允许跨域,发送Preflight请求将使用OPTIONS方法,同时带上以下头部:
- 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:Preflight缓存时间(秒),在缓存期内无需再发Preflight请求
跨浏览器的CORS实现
1
2
3
4
5
6
7
8
9
10
11
12
13
14function createCORSRequest(method, url) {
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr) {
xhr.open(method, url, true);
}
//针对IE浏览器
else if (typeof XDomainRequest != "undefined") {
xhr = new XDomainRequest();
xhr.open(method, url);
} else {
xhr = null;
}
return xhr;
}
其它跨域技术
JSONP
JSONP全称JSON with padding(填充式JSON),JSONP由两部分组成:回调函数与数据,例如请求:http://www.xxx.com/?callback=handleResponse
,当浏览器收到响应后将执行handleResponse方法
使用方式:通过动态<script>
元素使用,使用时为<script>
元素的src指定跨域URL,请求完成后将会立即执行回调1
2
3
4
5
6
7function handleResponse(res) {
console.log("服务器发送:" + res.text);
}
var script = document.createElement("script");
script.src = "http://www.xxx.com/?callback=handleResponse";
document.body.insertBefore(script, document.body.firstChild);
缺点:
1.不安全,因为代码不确定
2.不容易确定JSONP请求失败