AJAX是异步的JavaScript和XML(Asynchronous JavaScript And XML)。就是使用 XMLHttpRequest 对象与服务器通信。 它可以使用JSON,XML,HTML和text文本等格式发送和接收数据。AJAX可以在不重新刷新页面的情况下与服务器通信,交换数据,或更新页面。
AJAX最主要的两个特性:
- 在不重新加载页面的情况下发送请求给服务器。
- 接受并使用从服务器发来的数据。
1.总结 Ajax 请求共有多少种回调呢?
回调函数:如果要处理 $.ajax() 得到的数据,则需要使用回调函数:beforeSend、error、dataFilter、success、complete。
- beforeSend
在发送请求之前调用,并且传入一个 XMLHttpRequest 作为参数。 - error
在请求出错时调用。传入 XMLHttpRequest 对象,描述错误类型的字符串以及一个异常对象(如果有的话) - dataFilter
在请求成功之后调用。传入返回的数据以及 "dataType" 参数的值。并且必须返回新的数据(可能是处理过的)传递给success 回调函数。4. success
当请求之后调用。传入返回后的数据,以及包含成功代码的字符串。 - complete
当请求完成之后调用这个函数,无论成功或失败。传入 XMLHttpRequest 对象,以及一个包含成功或错误代码的字符串。
2.造成跨域的原因
下面三条同时满足时,才会产生跨域:
- 浏览器同源策略的限制
- DOM同源策略:禁止对不同源的页面的DOM进行操作,主要包括iframe、canvas之类的。不同源的iframe禁止数据交互的,含有不同源数据的canvas会受到污染而无法进行操作。
- XmlHttpRequest同源策略:禁止不同源的AJAX请求,主要用来防止CSRF攻击
- 协议、域名、端口号不完全相同
- XHR(XMLHttpRequest)请求
3.有哪些办法可以解决跨域?
- CORS(跨资源共享- Cross-origin resource sharing)
CORS 是W3C推荐的一种官方方案,能使服务器支持XmlHttpRequest的跨域请求。CORS只需要添加一些HTTP头,让服务器声明允许的访问来源。
使用CORS时,异步请求会被分为简单请求和非简单请求:
- 对于简单请求,浏览器直接发出CORS请求。在头信息中自动添加一个Origin字段(本次请求来自哪个源:协议+域名+端口),服务器根据这个值,决定是否同意这次请求。
- 非简单请求之前,会增加一次HTTP查询请求,称为“预检”请求。
浏览器先询问服务器,当前网页所在域名是否在服务器许可名单中,以及可以使用哪些HTTP动词和头信息字段,只有得到肯定的答复,浏览器才会发出XMLHttpRequest请求。
- JSONP
可以在js中绕过同源策略,并发起跨域HTTP请求的使用模式。
同源策略有一个显著的例外,HTML脚本元素可以规避SOP检查,所以我们可以通过script标签动态注入脚本向其他源发送请求。
局限性:
- JSONP只适用于http的get请求。
- JSONP缺乏错误处理机制,如果动态注入脚本成功,就会执行回调函数,如果错误,没有任何提示信息;即当遇到4,5等错误的时候,没法找到错误的原因;
- 在安全方面,借助JSONP有可能进行跨站请求伪造(CSRF)攻击,当一个恶意网站使用访问者的浏览器向服务器发送请求并进行数据变更时,被称为CSRF攻击。由于请求会携带cookie信息,服务器会认为是用户自己想要提交表单或者发送请求,而得到用户的一些隐私数据
3.代理服务器
服务器与服务器之间不存在跨域问题,因此可以通过设置代理服务器得方式解决跨域问题。不过要注意与代理服务器的跨域问题。
4.自己封装一个ajax对象
/**
options = {
url: "",
method: "",
headers: {}, // 传给
data: "", // 传给服务器的参数
success: function(result) {}, // 请求成功后调用此方法
fail: function(error) {} // 请求失败或出错后调用此方法
}
**/
var request = function(options) {
// code this here
options.method = ptions.method.toUpperCase();
var ajax = new XMLHttpRequest();
if (options.method === 'POST') {
ajax.open("POST",options.url,true)
ajax.setRequestHeader('Content-Type', options.headers);
ajax.send(options.data);
}
else {
ajax.open("GET",options.url,true)
ajax.send();
}
ajax.onreadystatechange = function () {
if(ajax.readyState == 4){
if((ajax.status >= 200 && ajax.status < 300)||ajax.status == 304){
options.success();
}
}
else{
options.fail();
}
};
};
5.处理服务器请求
readyState属性有5个值,你可以检查readyState属性并相应作出反应,其按照执行的顺序排列:
- 0:未发送
- 1:打开
- 2:接收到首标
- 3:加载中
- 4:完成
当readyState等于4时,ajax请求已经完成,检查对象的status属性可以完成确认工作,该属性代表服务器对资源请求的相应代码。这些服务器代码包括:
- 200: 正常
- 301: 永久性移动
- 304: 未作修改
- 307: 临时重定向
- 401: 未授权
- 403: 禁止访问
- 404: 未找到
- 500: 服务器内部错误
当函数做好准备处理服务器相应时,它可以从下面两个属性之一找到相应数据:responseXML和responseText。前者用在返回数据为XML格式时,后者在返回数据不是XML格式时填充,因此大部分时候都使用这个属性。该属性存储一个字符串,使用方法与其他字符串相同。