Ajax原理
Ajax:Asynchronous JavaScript and XML 异步的Javascript和XML
Ajax可以通过XMLHttpRequest对象与服务器进行交互,实现在不刷新整个网页的情况下,获取数据,再通过javascript脚本操作DOM将数据变化插入到网页中,达到网页部分内容更新的效果。
Ajax创建对象及属性和方法
创建异步调用对象XMLHttpRequest
var xmlHttp=null;
if(window.XMLHttpRequest)
{
xhr = new XMLHttpRequest(); //IE7以上及其他常见浏览器
}
else
{
xhr = new ActiveXObject("Microsoft.XMLHTTP");//IE6、IE5
}
- 当考虑兼容问题,IE6及以下不支持XMLHttpRequest对象,可以使用ActiveObject(“Microsoft.XMLHHTP”)创建异步调用的对象
- null值表示一个空对象指针,使用typeof操作符检测null值会返回“object”,所以当定义的变量准备在将来用于保存对象,那么最好将该变量初始化为null而不是其他值
XHR对象的属性和方法
open方法: 规定请求的类型、URL 以及是否异步处理请求。对应三个参数
- method:请求的方法
- url:文件在服务器上的位置
- async:true(异步)或 false(同步)
send方法:将请求发送到服务器(仅用于 POST 请求)
注:如果不需要通过请求主体发送数据,则必须传入null。一般get请求不需要传入参数,而对于post请求,如果需要像 HTML 表单那样 POST 数据,需使用 setRequestHeader() 来添加 HTTP 头。然后在 send() 方法中规定希望发送的数据。
通过send()发送之后,会接受到响应,响应的数据会自动填充XHR对象的属性。
- responseText:作为响应主体被返回的文本
- responseXML:如果响应的内容类型是”text/xml”或”application/xml”,这个属性中将保存包含着相应数据的XML DOM文档。
- status:响应的http状态
- statusText:Http状态的说明
接收到响应后,一般是先检查status,来确定响应是否成功返回,状态代码200表示成功(以2开头即表示成功),这是responseText就可以被访问了。而状态代码为304表示请求的资源并没有被修改,可以直接使用浏览器中缓存的版本,因此这种响应也是有效的。
- readyState
存有 XMLHttpRequest 的状态,检测请求/响应过程的当前活动阶段从 0 到 4 发生变化
- 0: xhr对象已创建但未初始化(未调用open方法)
- 1: 服务器连接已建立(已调用send方法,正在发送请求)
- 2: 请求已接收
- 3: 请求处理中
- 4: 请求已完成,且响应已就绪(数据接收完毕)
!!! readystate的值每次发生改变都会触发readystatechange事件。当值为4时表示所有的数据已经准备就绪。
xhr.onreadystatechange=function(){
if(readyState==4){
if((xhr.status>=200&&xhr.status<300)||xhr.status==304){
alert(xhr.responseText);
}else{
alert("Request waw unseccessful:"+"xhr.status");
}
}
};
xhr.send(null);
- abort方法
在接受到响应之前,我们还可以使用abort()方法来取消异步请求 - setRequestHeader()方法、getResponseHeader()方法、getAllResponseHeader()方法
创建Ajax的过程
- 创建一个异步调用对象XMLHttpRequest
- 创建一个新的HTTP请求,并指定该HTTP请求的方法、URL及异步与否(open)
- 设置响应HTTP请求状态变化的函数.(readystatechange)
- 发送HTTP请求(send)
- 获取异步调用返回的数据.
- 使用JavaScript和DOM实现局部刷新.
<body>
<input type="button" value="Ajax提交" onclick="Ajax();" />
<div id="respText"></div>
<script>
function Ajax() {
//创建XMLHttpRequest对象
var xml = null;
if (window.ActiveXObjct) {
xml = new ActiveXObject("Microsoft.XMLHTTP");
} else if (window.XMLHttpRequest) {
xml = new XMLHttpRequest();
}
if (xml != null) {
// 开启http请求
xml.open('GET', 'test.php', true);
// 设置响应HTTP请求状态变化的函数,对readystate进行监听
xml.onreadystatechange = function () {
if (xml.readystate == 4) {
if (xml.status >= 200 && xml.status < 300 || xml.status == 304) {
// 获取异步调用返回的数据,使用JavaScript和DOM实现局部刷新.
document.getElementById('respText').innerHTML = xml.responseText;
} else {
alert(xml.status + ':' + xml.statusText);
}
}
}
// 发送请求
xml.send(null);
}
}
</script>
</body>
Ajax的优势和不足
Ajax的优势
- 不需要插件的支持
- 减轻服务器和宽带的负担
- 显示更快,提升用户体验
- 减少通信量的消耗
Ajax的缺点
- 浏览器对XMLHttpRequest独享的支持度不足
- 破坏浏览器前进、后退按钮的正常功能
- 对搜索引擎的支持的不足
同源策略
同源策略,它是由Netscape提出的一个著名的安全策略,默认情况下,XHR对象只能访问与包含他的页面位于同一个域中的资源,这种安全策略可以预防某些恶意行为。
同源是指:协议、域名和端口相同。
跨域
当一个请求url的协议、域名、端口三者之间任意一与当前页面地址不同即为跨域。
例如:html中的link标签的href属性,img标签的src属性,script标签的src属性
Ajax受同源策略的限制无法实现跨域。要实现跨域可以有哪些操作呢
常见的有Jsonp和CORS
Jsonp
JSONP 是 JSON with padding(填充式 JSON 或参数式 JSON)
原理
动态创建 script 标签,然后利用 script 的src 不受同源策略约束来跨域获取数据。服务器收到请求后,将json数据放在一个指定名字的回调函数(callback)里传回来。
function addScriptTag(src) {
var script = document.createElement('script');
script.setAttribute("type","text/javascript");
script.src = src;
document.body.appendChild(script);
}
window.onload = function () {
addScriptTag('http://example.com/ip?callback=foo');
}
function foo(data) {
console.log('Your public IP address is: ' + data.ip);
};
//jQuery方式
$.ajax({
async : true,
url : "http://example.com/ip",
type : "GET",
dataType : "jsonp", // 返回的数据类型,设置为JSONP方式
jsonp : 'callback', //指定一个查询参数名称来覆盖默认的 jsonp 回调参数名 callback
jsonpCallback: 'foo', //设置回调函数名
data : {},
success: function(){
... //处理数据
}
});
优缺点
- 兼容性好,支持老式浏览器,简单易用
- 只支持GET方法请求
- 要保证跨域的安全性,不然会给网页的带来一些恶意代码
websocket
WebSocket是一种通信协议,使用ws://(非加密)和wss://(加密)作为协议前缀。该协议不实行同源政策,只要服务器支持,就可以通过它进行跨源通信。
服务器可以根据客户端传来的报文中origin这个字段,判断是否许可本次通信。如果该域名在白名单内,服务器就会做出相应的请求响应
CORS
CORS(Cross-origin resource sharing)跨域资源共享,它允许浏览器向跨源服务器,发出XMLHttpRequest请求,从而克服了AJAX只能同源使用的限制。
实现CORS通信的关键是服务器。只要服务器实现了CORS接口,就可以跨源通信。
原理
客户端通过服务器端返回的响应中设置的Access-Control-Allow-Origin进行判断。如果浏览器检测到相应的设置,就可以允许Ajax进行跨域的访问。
不同的请求方式和请求的字段可能会有差异,具体参照 –>> 阮一峰-跨域资源共享
优缺
- 支持所有HTTP类型的请求
- 不是所有浏览器都支持