1.
如果要处理 $.ajax() 得到的数据,则需要使用回调函数:beforeSend、error、dataFilter、success、complete
。
-
beforeSend
在发送请求之前调用,并且传入一个 XMLHttpRequest 作为参数。 -
error
在请求出错时调用。传入 XMLHttpRequest 对象,描述错误类型的字符串以及一个异常对象(如果有的话) -
dataFilter
在请求成功之后调用。传入返回的数据以及 "dataType" 参数的值。并且必须返回新的数据(可能是处理过的)传递给 success 回调函数。 -
success
当请求之后调用。传入返回后的数据,以及包含成功代码的字符串。 -
complete
当请求完成之后调用这个函数,无论成功或失败。传入 XMLHttpRequest 对象,以及一个包含成功或错误代码的字符串。
2.
var ajax = new XMLHttpRequest();
ajax.prototype.request(url,style,fun) = request(url,style,fun);
ajax.prototype.request(url,style,fun,text) = request(url,style,fun,text);
function request(url,style,fun){
this.open(style,url,true);
myCallback(this);
}
function request(url,style,fun,text){
this.send(style,url,text,true);
myCallback(this);
}
function myCallback(xhr) {
alert(xhr.responseText);
}
ajax.request(“somefile.txt”, ”get”, myCallback);
ajax.request(“script.php”, ”post”, myCallback, ”first=John&last=Smith”);
3.
原因:(3个原因同时满足,才可能产生跨域问题)
- 浏览器限制
- 跨域(协议,主机名,端口号中有一个不同就产生跨域)
- XHR(XMLHttpRequest)请求
4.
- JSONP方式解决跨域问题
jsonp解决跨域问题是一个比较古老的方案(实际中不推荐使用),这里做简单介绍(实际项目中如果要使用JSONP,一般会使用JQ等对JSONP进行了封装的类库来进行ajax请求)
实现过程:
- 客户端网页网页通过添加一个<script>元素,向服务器请求JSON数据,这种做法不受同源政策限制。请求时,接口地址是作为构建出的脚本标签的src的,这样,当脚本标签构建出来时,最终的src是接口返回的内容
- 服务端对应的接口在返回参数外面添加函数包裹层
- 由于<script>元素请求的脚本,直接作为代码运行。这时,只要浏览器定义了foo函数,该函数就会立即调用。作为参数的JSON数据被视为JavaScript对象,而不是字符串,因此避免了使用JSON.parse的步骤。
注意,一般的JSONP接口和普通接口返回数据是有区别的,所以接口如果要做JSONO兼容,需要进行判断是否有对应callback关键字参数,如果有则是JSONP请求,返回JSONP数据,否则返回普通数据
- CORS解决跨域问题
各个后台语言都有对应配置以用于解决跨域问题。PHP后台配置、Node.js后台配置(express框架)、JAVA后台配置、JAVA Spring Boot配置、NET后台配置。 - 代理请求方式解决接口跨域问题
与前面的方法不同,前面CORS是后端解决,而这个主要是前端对接口进行代理,也就是:
- 前端ajax请求的是本地接口
- 本地接口接收到请求后向实际的接口请求数据,然后再将信息返回给前端
- 一般用node.js即可代理
- OPTIONS预检的优化
Access-Control-Max-Age:
这个头部加上后,可以缓存此次请求的秒数。
在这个时间范围内,所有同类型的请求都将不再发送预检请求而是直接使用此次返回的头作为判断依据。
非常有用,可以大幅优化请求次数。
5.
var request = function(options) {
options = options || {};
options.data = options.data || {};
var json = options.jsonp ? jsonp(options) : json(options);
function json(options) {
options.type = (options.type || 'GET').toUpperCase();
options.data = formatoptions(options.data);
var xhr = null;
if (window.XMLHttpRequest) {
xhr = new XMLHttpRequest();
} else {
xhr = new ActiveXObjcet('Microsoft.XMLHTTP');
};
}
function ajax(url, success, fail) {
var xhr = null;
xhr = new XMLHttpRequest()
xhr.open('get', url, true)
xhr.send(null);
xhr.onreadystatechange = function() {
if (xhr.readyState == 4) {
if (xhr.status == 200) {
success(xhr.responseText);
} else { // fail
fail && fail(xhr.status);
}
}
}
}
json.ajax(options.url,options.success,options.fail);
}
options = {
url: "",
method: "",
headers: {}, // 传给
data: "", // 传给服务器的参数
success: function(result) {}, // 请求成功后调用此方法
fail: function(error) {} // 请求失败或出错后调用此方法
}
网友评论