【问题标题】:jQuery Ajax post request stuck on pending on ChromejQuery Ajax 发布请求在 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-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”,那么您尝试访问的后端代码也应该受到保护。我也遇到过类似的问题。

标签: javascript jquery ajax google-chrome


【解决方案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 重定向)。不幸的是,我现在无法知道。我会投票赞成你的答案,因为它很有帮助,但我不能接受。
  • 如果您要上传文件,最好在表单数据回发之外处理。
猜你喜欢
  • 1970-01-01
  • 2015-03-16
  • 2012-02-02
  • 2014-01-30
  • 1970-01-01
  • 1970-01-01
  • 2018-03-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多