jQuery Ajax 发布请求在 Chrome 上挂起

Posted

技术标签:

【中文标题】jQuery Ajax 发布请求在 Chrome 上挂起【英文标题】:jQuery Ajax post request stuck on pending on Chrome 【发布时间】:2019-05-21 19:49:01 【问题描述】:

我有一个 jQuery 客户端向 Spring 控制器发出 Ajax 发布请求。 在服务器端,没有记录任何错误。 在客户端,请求在等待很长时间(几分钟)中停滞,然后可能会因 ERR_SPDY_PROTOCOL_ERROR 或 ERR_CONNECTION_CLOSED 而失败。

这个问题可以在 Chrome 上重现,但不能在 Firefox 上重现。已验证受影响版本为 70.0.3538.77,可能还有其他版本。 此外,问题发生在应用程序的特定部署上,而不是其他地方,开发或生产。

客户端在该环境中发送 HTTPS 2 请求。在开发环境上是 HTTP 1.1。在服务器上,所有请求都记录为 1.1。

由于没有明显的原因,请求开始通过,但这是一个反复出现的问题,希望解决它。 由于问题开始发生,我无法重现它并检查问题是否与服务器的连接过多(超过 6 个)。 我用了三台DNS服务器,最后一台是谷歌的8.8.8.8。

我正在寻找代码修复或提示这是否与服务器设置有关。 我几乎可以肯定它是客户端代码和网络的结合。

问题不是什么:

防病毒 (Chrome net::ERR_INCOMPLETE_CHUNKED_ENCODING error)

预测服务相关 (Stalled and pending ajax requests by JQuery in Chrome) - 不过,关于代理和连接的评论似乎更相关。

广告拦截器扩展/插件 (Failed to load resource under Chrome)

我尝试过的失败:

https://www.reddit.com/r/chrome/comments/3ej5ua/err_spdy_protocol_error/

https://www.itechgyan.com/err_spdy_protocol_error/

jQuery Ajax requests are getting cancelled without being sent

什么不能回答问题:

Ajax request over https hangs for 40 seconds in chrome only

在客户端,我尝试过清除浏览器数据、刷新套接字和隐私浏览/隐身。

有时,很少会绕过错误的唯一事情是隐身并刷新套接字并从 chrome://net-internals/#events 清空缓存

var formData = new FormData();

formData.append( /* ... */ );

//...

$.ajax(
    type: "POST",
    url: "/somepath/update",
    cache: false,
    data: formData,
    contentType: false,
    processData: false,
    success: function(result) 
        //...
    ,
    fail: function(result) 
        //....
    ,
    error: function( jqXHR, textStatus, errorThrown )
        alert(textStatus + ":" + errorThrown);
    
);

使用 $.post 的单独请求正在处理:

$.post("someotherpath/update", $("#someForm").serialize())
    .done(function (data) 
        //...
     )
     .fail(function (data) 
         //...
     )
     .always(function () 
         //...
     );

服务器端:

@RequestMapping(value="/somepath/update", method = RequestMethod.POST, produces = "application/json;charset=UTF-8")
public @ResponseBody String update(ModelClass model) 
    JSONObject result = new JSONObject();
    //...
    return result.toString();

如果相关,则有以下过滤器。恐怕我现在不能发布更多:

@Configurable
public class Filter1 extends OpenEntityManagerInViewFilter implements Filter

    public void doFilterInternal(HttpServletRequest httpReq, HttpServletResponse httpResp, FilterChain chain)
        throws ServletException, IOException 
        //...
    



@Configurable
public class Filter2 extends OncePerRequestFilter implements Filter

    public void doFilterInternal(HttpServletRequest httpReq, HttpServletResponse httpResp, FilterChain chain)
        throws ServletException, IOException 
        //...
    


@Order(/* very small integer */)
public class Filter3 extends OncePerRequestFilter 


预期的结果是代码应该通过成功回调。 相反,请求会停留在等待状态几分钟,然后进入错误回调。

【问题讨论】:

你的 jquery 版本是...? :D 您是否尝试过使用 postman 或 curl 发送基本请求以确认服务器对相同类型的请求响应正常? 感谢您的评论@CodyG。版本是 1.7.2。我没有尝试过邮递员,但我想尝试使用 Firefox 就足够了。 需要考虑的事情:我遇到了各种问题,因为我在 chrome://flags/ 中打开了一个标志。 experimental web platform features 标志打开了一些 Web 服务器无法处理的新标头。尝试在测试时重置这些标志。 能否请您看一下 chrome 开发者工具(在 Win 上按 F12)然后是 Network 选项卡,然后尝试运行您的代码。它应该显示您正在发送的数据以及可能出现的任何错误,并让我们知道结果是什么。也尝试比较 Chrome/Firefox/Chrome incognito 上的输出 检查协议。如果页面 url 是“https”,那么您尝试访问的后端代码也应该受到保护。我也遇到过类似的问题。 【参考方案1】:

$.post 在后台调用$.ajax,只是默认了几个选项。

$.post 默认 contentType"application/x-www-form-urlencoded; charset=UTF-8",这将与您的序列化表单数据负载一致。

您对$.ajax 的调用将contentType 设置为false——这可能会导致浏览器向服务器发送飞行前OPTIONS 请求,这可能会导致您遇到的行为有所不同。

我建议阅读jQuery.ajax() 的详细信息以及基于options passed here 的各种行为

【讨论】:

感谢您的回答。我需要将 contenttype 设置为 false,因为我正在发送一些文件。但你是对的。它可能是一个跨域请求(由于 DNS 重定向)。不幸的是,我现在无法知道。我会投票赞成你的答案,因为它很有帮助,但我不能接受。 如果您要上传文件,最好在表单数据回发之外处理。

以上是关于jQuery Ajax 发布请求在 Chrome 上挂起的主要内容,如果未能解决你的问题,请参考以下文章

AJAX 请求 + jQuery 的内存泄漏

Django 在 JQuery AJAX 请求中说 is_ajax 是错误的

跨域的 jQuery AJAX 对于 Chrome 等工作正常,但不能在 IE10 中发送数据,也不能在 IE <= 9 中发送请求

jquery $.ajax 在 Chrome 或 Firefox 中调用会导致 401 未经授权的响应,但在 IE 中有效

Chrome 不知道 POST 请求

jQuery ajax CORS 请求