【发布时间】:2017-05-13 20:17:26
【问题描述】:
我正在通过 AJAX 和 FormData 作为输入文件控件更改事件的一部分上传文件。 $form 变量是对我的表单的 jQuery 引用(如果这不明显的话)。
$.ajax(url, {
contentType: false,
data: new FormData($form[0]),
method: "post",
processData: false
}).fail(function(xhr, status, error) {
console.log(xhr.responseText);
console.log(status);
console.log(error);
})
当我在本地测试时,这适用于 IE、FF 和 Chrome。一旦应用程序部署到我们的 QA 环境中,它只会在 FF(50.1.0 64 位)中停止工作。我可以在网络选项卡中看到 POST,但左侧的圆圈保持灰色,就好像它仍在等待中一样。
请求确实“失败”并调用了我的函数,但没有提供任何有趣的信息(屏幕截图中也提供了 console.log 输出)。
我认为这可能是 CORS 问题,但在 about:config 中摆弄并安装 CORS Everywhere 插件并没有产生结果变化。
本地测试和 QA 测试环境之间的显着区别在于 QA 环境是负载平衡的 SSL 卸载配置。我们使用的 SSL 证书是通配符,这意味着它适用于任何网站 *.company.com。本地测试是纯文本。
我确实尝试了here 提出的一些建议,但无济于事。
我尝试的最后一件事是使用 Fiddler 查看 FF 和应用程序服务器之间发生了什么。当 Fiddler 设置为解密 HTTPS 流量时,该过程开始工作(奇怪)。当 Fiddler 正在捕获但不解密 HTTPS 流量时,它不起作用(就像 Fiddler 没有运行一样)。这让我相信它可能与证书有关?
我正在寻找有关可能是什么问题的建议/想法。
编辑:
我做了进一步的实验,确定提交一个空的FormData会POST到服务器:
$.ajax(url, {
contentType: false,
data: new FormData(),
method: "post",
processData: false
})
带有一些垃圾文本键/值对的 FormData 也是如此:
var d = new FormData();
d.append("key", "value");
$.ajax(url, {
contentType: false,
data: d,
method: "post",
processData: false
})
当尚未选择任何文件时,POST 也会成功(FormData with empty File)。
我还确定通过 HTTP 而不是 HTTPS 访问应用程序允许 Firefox 重新开始工作(尽管我仍然不明白为什么)。失败的组合似乎是 HTTPS + 文件数据。我还确认了触发错误回调时 xhr.status = 0 和 xhr.readyState = 0。
使用 ProcMon,我能够确定我的请求总是离开 Firefox 并到达我们的负载均衡器(SSL 终止的地方),但从未离开负载均衡器(没有匹配的 Apache 日志条目)。同样的配置仍然适用于 IE 和 Chrome,所以我不确定 Firefox 是否正在以这样一种方式形成请求,以至于它们被负载平衡设备 (Cisco ACE) 拒绝。
【问题讨论】:
-
I thought perhaps it could be a CORS issue- 那么,请求是跨源的吗?如果是这样,服务器是否使用适当的 CORS 标头进行响应? -
那么调用是否发送到服务器?如果您在没有表单数据的情况下拨打电话,它会起作用吗?帮助您调试这将非常困难....
-
@Jaromanda X:请求不是跨源的。我只是因为在发布之前搜索了一些点击而最终到达那里。
-
您发布的代码是否完整?表单数据有什么“不寻常”的地方吗?
-
@epascarello:我不认为呼叫正在发送到服务器,不。我可以尝试在没有 FormData 的情况下拨打电话(我将发送 {}),看看会发生什么。
标签: javascript ajax firefox multipartform-data