一、前言
这几天在调试页面ajax的时候,一直报错。代码如下:
$.ajax({
cache: true,
type: "POST",
url: url,
data: data,
dataType: 'json',
error: function () {
alert("Connection error.");
},
success: function (data) {
// ...
}
});
奇怪的是,后台显示请求时已经发到了。
加入以下代码,然后经过浏览器调试。
$.ajax({
cache: true,
type: "POST",
url: url,
data: data,
dataType: 'json',
error: function (XMLHttpRequest) {
alert("Connection error.");
console.log("XMLHttpRequest.status: " + XMLHttpRequest.status);
console.log("XMLHttpRequest.readyState: " + XMLHttpRequest.readyState);
},
success: function (data) {
// ...
}
});
网上的调试代码在error事件触发的函数中还加入了textStatus
, errorThrown
两个对象,但是我调试的时候发现并没有定义,没什么用。
运行之后打印信息如下
XMLHttpRequest.status: 0
XMLHttpRequest.readyState: 0
想要通过这几个信息来分析问题,首先要知道这个status
代表的是什么。
二、问题分析
1.readyState
根据w3c描述,readyState存着XMLHttpRequest的状态,从 0 到 4 发生变化。
0: 请求未初始化
1: 服务器连接已建立
2: 请求已接收
3: 请求处理中
4: 请求已完成,且响应已就绪
2.XMLHttpRequest status = 0
刚看到很奇怪,为什么状态码也会返回一个0,不应该是200/404之类的吗?
按照这个网站对XMLHttpRequest的说明:
The status attribute must return the result of running these steps:
status的值一定会返回运行这些步骤的结果。
1、If the state is UNSENT or OPENED, return 0.(如果状态是UNSENT或者OPENED,返回0)
2、If the error flag is set, return 0.(如果错误标签被设置,返回0)
3、Return the HTTP status code.(返回HTTP状态码)
如果在HTTP返回之前就出现上面两种情况,就出现0了。
分析了一下原因:
- url不存在(排除) – Controller层定义正确
- url不可达(排除) – 后台确实接收到请求了,而且处理正确
- 发送了跨域请求(排除) – 使用CORS Filter, 测试发现也不是
- 数据格式错(排除) – 浏览器和后台调试发现,数据格式正确
- ajax在完成之前请求已经被取消(ajax请求没有发出) – 确实是canceled,但是请求确实发出了
- 请求超时 – 确认问题
三、解决方案
- 使用同步请求
$.ajax({
cache: true,
type: "POST",
url: url,
data: data,
dataType: 'json',
async: false, // 同步操作
// timeout : 1000, // 也可以加入延时防止ajax报错
error: function () {
alert("Connection error.");
},
success: function (data) {
// ...
}
});
网友评论