1事故情况:在前端ajax请求数据的时候,有时候会向后台一次性发送两次请求,,这两次请求第一次无返回数据,第二次才会返回正确数据。
2事故原因:原来对于跨域,有两种不同的请求类型。分别为简单跨域请求和复杂跨域请求(带预检的跨域请求)。
3复杂跨域:
非简单请求是那种对服务器有特殊要求的请求,比如请求方法是PUT
或DELETE
,或者Content-Type
字段的类型是application/json
。
非简单请求的CORS请求,会在正式通信之前,增加一次HTTP查询请求,称为"预检"请求(preflight)。
预检请求为OPTIONS请求,用于向服务器请求权限信息的。
预检请求被成功响应后,才会发出真实请求,携带真实数据。
4解决方式:而本项目,后台采用token检验机制,前台发送请求必须将token放到request header中,而请求头中携带自定义参数,浏览器就认为请求是复杂跨域请求,所以浏览器在真正 请求之前会发送一次预检请求,检测服务器是否支持真实请求进行跨域访问。
5其他问题:刚开始执行的时候,提示跨域。服务端设置Access-Control-Allow-Origin: *允许跨域
但是还报错:还是得服务端设置允许的header。
Access-Control-Allow-Headers:后面加允许的header的参数,中间用逗号隔开。
还是会发送两次请求:
后台可以通过设置Access-Control-Max-Age来控制浏览器在多长时间内(单位s)无需在请求时发送预检请求。
6补充点:Ajax设置自定义请求头的两种方法
方法一:
$.ajax({
type: "post",
url:"http://---",
contentType: "application/json;charset=utf-8",//header中参数服务端通常是根据请求头(headers)中的 Content-Type 字段来获知请求中的消息主体是用何种方式编码,再对主体进行解析。application/json;用来告诉服务端消息主体是序列化后的 JSON 字符串
data :{},
dataType: "json",
//重点
beforeSend: function (XMLHttpRequest) {
XMLHttpRequest.setRequestHeader("token", "...");
},
success: function (data) {
alert(data);
},error:function(error){
console.log(error);
}
});
方法二:
$.ajax({
type: type,
headers: {
'token':$.cookie('token')
},
url: url,
data: data,
success: function(data) {
},
error: function(err) {
}
});