【开发笔记】ajax交互报错调试,请求失败状态码为0时的解析,附解决方案

Richard_Yi 2018年03月04日 125次浏览

本文为历史博客迁移,实际发布时间:2018.04.03 13:50

一、前言

这几天在调试页面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) {
            // ... 
        }
    });

参考资料

  1. https://blog.csdn.net/iaiti/article/details/42192659
  2. https://blog.csdn.net/changqing5818/article/details/53932463
  3. http://www.w3school.com.cn/ajax/ajax_xmlhttprequest_onreadystatechange.asp