Javascript Ajax请求有时会失败-使用和不使用jQuery 介绍

Javascript Ajax请求有时会失败-使用和不使用jQuery 介绍,javascript,jquery,ajax,Javascript,Jquery,Ajax,这个问题似乎比实际时间长,但我试图保持一个干净的结构 首先,我有一个webapp,它需要非常小的文件大小,才能在0){ 选项。重试--; ajax(选项); }否则{ 选项。错误(请求); } }; request.onreadystatechange=函数(){ var delta=new Date().getTime()-request.startTime; if(request.readyState==4){ 如果(request.status>=200&&request.status=r

这个问题似乎比实际时间长,但我试图保持一个干净的结构

首先,我有一个webapp,它需要非常小的文件大小,才能在<10秒内完全加载(无缓存)到您的智能手机上。这要求我不要使用像jQuery这样的库(不管怎样,这并不重要,请参见下文)

没有jQuery 我基本上使用了创建这个短包装:

function ajax(options) {
    var request;

    if (window.XMLHttpRequest) {
        request = new XMLHttpRequest();
    } else {
        request = new ActiveXObject("Microsoft.XMLHTTP");
    }

    request.timeout = 6500;
    request.ontimeout = function () {
        // not called, 6.5s is too high for a timeout anyway, checked this one first
        options.error(request);
    };

    request.onreadystatechange = function () {
        if (request.readyState == 4) {
            if (request.status >= 200 && request.status < 400) {
                options.success(request.responseText);
            } else {
                options.error(request);
            }
        }
    };

    request.open("GET", options.url, true);
    request.send();
}
然而,即使是这一个,有时也会在statusCode=0时失败(updateTimeout设置为65s,因为我“可以等待这一个”)。此外,它与第一个代码段中的Web服务器不同

到目前为止我试过什么?
  • 做一些研究(发现很多人想使用CORS,而我并不想这么做)
  • 通过向url添加时间戳阻止浏览器使用网站的缓存版本(
    “&cache=“+new Date().getTime()
    ,也不起作用)
  • 检查Web服务器的配置是否错误(这不是问题的根源,我甚至尝试过在相同的时间间隔内使用短Python脚本(如Ajax调用)轮询站点,但都成功了)
  • 尝试了不同的浏览器:这主要发生在Firefox中,尽管Chrome似乎偶尔也会失败
最后问题 为什么会这样?我不能重复地复制它,只是有时候会发生。这是不是一个浏览器错误,使得第n个Ajax调用都失败了?您是否有任何不同的方法来解决这个问题(最好使用纯Javascript)

更新
我做了更多的研究,这次是和wireshark。我记录了导致
状态=0
的请求,然后查看了这些包的TCP流图,所有请求都从服务器得到了答案,我想这不是服务器端的问题

所以我通过做大量测试来解决这两个问题。jQueryOne非常简单,升级到jQuery2.1.4解决了这个问题,我不想知道是什么导致了这个问题,它现在可以工作了

对于第二个问题,我将超时时间减少到500毫秒,然后遇到一个超时,导致调用
onreadystate
,即使请求没有完全完成(就及时获得答案而言),因此得到
status=0
。为什么以前会发生这种情况,请参见上文。为了确保超时不仅仅是“随机的”,我添加了一个重试计数器并修改了我的Ajax函数:

function ajax(options) {
    var request;

    if (options.retry === undefined) {
        options.retry = 3; // modify here for default retry count
    }

    if (window.XMLHttpRequest) {
        request = new XMLHttpRequest();
    } else {
        request = new ActiveXObject("Microsoft.XMLHTTP");
    }

    request.timeout = options.timeout ? options.timeout : 500; // modify here for default timeout
    request.ontimeout = function () {
        if (options.retry > 0) {
            options.retry--;
            ajax(options);
        } else {
            options.error(request);
        }
    };

    request.onreadystatechange = function () {
        var delta = new Date().getTime() - request.startTime;

        if (request.readyState == 4) {
            if (request.status >= 200 && request.status < 400) {
                options.success(request.responseText);
            } else if (request.status === 0 && delta >= request.timeout) {
                // do nothing as this was "just a timeout"
            } else {
                options.error(request);
            }
        }
    };

    request.startTime = new Date().getTime();
    request.open("GET", options.url, true);
    request.send();
}
函数ajax(选项){
var请求;
如果(options.retry==未定义){
options.retry=3;//在此处修改默认重试计数
}
if(window.XMLHttpRequest){
请求=新的XMLHttpRequest();
}否则{
请求=新的ActiveXObject(“Microsoft.XMLHTTP”);
}
request.timeout=options.timeout?options.timeout:500;//在此处修改默认超时
request.ontimeout=函数(){
如果(options.retry>0){
选项。重试--;
ajax(选项);
}否则{
选项。错误(请求);
}
};
request.onreadystatechange=函数(){
var delta=new Date().getTime()-request.startTime;
if(request.readyState==4){
如果(request.status>=200&&request.status<400){
options.success(request.responseText);
}else if(request.status==0&&delta>=request.timeout){
//什么也不做,因为这只是“超时”
}否则{
选项。错误(请求);
}
}
};
request.startTime=new Date().getTime();
打开(“GET”,options.url,true);
request.send();
}

0的
状态
表示请求甚至没有发送。您是否仔细检查了
options.url
中的值(发生错误时会显示什么)?这是Javascirpt,所以请确保没有对
选项的交叉访问。我也这么认为,但结果证明url是正确的。这可能是由于两个请求几乎同时发送造成的吗?我有一个ajax“线程”(JS中没有线程,我想你明白我的意思)和一个用户启动的ajax。检查服务器请求日志,看看服务器是否/如何处理请求。状态
0
确实表明请求已发送,但没有返回任何内容,通常是因为请求因某种原因被中止。希望这有帮助
$.ajax({
    url: url,
    dataType: "json",
    success: options.updateSuccess,
    error: options.updateError,
    timeout: options.updateTimeout
});
function ajax(options) {
    var request;

    if (options.retry === undefined) {
        options.retry = 3; // modify here for default retry count
    }

    if (window.XMLHttpRequest) {
        request = new XMLHttpRequest();
    } else {
        request = new ActiveXObject("Microsoft.XMLHTTP");
    }

    request.timeout = options.timeout ? options.timeout : 500; // modify here for default timeout
    request.ontimeout = function () {
        if (options.retry > 0) {
            options.retry--;
            ajax(options);
        } else {
            options.error(request);
        }
    };

    request.onreadystatechange = function () {
        var delta = new Date().getTime() - request.startTime;

        if (request.readyState == 4) {
            if (request.status >= 200 && request.status < 400) {
                options.success(request.responseText);
            } else if (request.status === 0 && delta >= request.timeout) {
                // do nothing as this was "just a timeout"
            } else {
                options.error(request);
            }
        }
    };

    request.startTime = new Date().getTime();
    request.open("GET", options.url, true);
    request.send();
}