我遇到的问题是,当我使用jquery ajax post,频率非常低(<2%)时,post参数永远不会进入服务器。我确实在访问日志中看到了帖子请求。它似乎只发生在IE上(我在日志中观察到了7,8和9)。
当我将呼叫从“post”类型切换到“get”类型时,问题就会消失。
有没有其他人在IE上见过这种奇怪的行为?谢谢!
我已经看到了各种ajax调用,但这是一个典型的:
var data= {
"guess" : "m1",
"eas" : "hello world"
};
$.ajax({
url: "http://myco.com/ajaxcall.action",
data: data,
type : 'post',
dataType: 'json',
success: function(data) {},
error: function() {}
});
更新:传递“cache:false”无法解决问题。
答案 0 :(得分:28)
我在上周跟踪了我自己的应用程序中的类似问题(使用Dojo,而不是JQuery)。根据您的描述和发生的频率,我会说这是同一个问题。
当在浏览器和服务器之间使用HTTP持久连接时(默认行为),服务器可以随时关闭HTTP连接。当浏览器在服务器关闭连接的同时开始发送新请求时,这会创建一个非常小的计时漏洞。大多数浏览器将使用不同的连接或打开新连接并重新发送请求。这是RFC 2616第8.1.4节中建议的行为:
客户端,服务器或代理可以在任何地方关闭传输连接 时间。例如,客户端可能已开始发送新请求 在服务器决定关闭“空闲”的同时 连接。从服务器的角度来看,连接正在进行 在闲置时关闭,但从客户的角度来看,a 请求正在进行中。
这意味着客户端,服务器和代理必须能够恢复 来自异步关闭事件。客户端软件应该重新打开 传输连接并重新传输中止的请求序列 只要请求序列是,就没有用户交互 幂等(见第9.1.2节)。
Internet Explorer 尝试在发生这种情况时重新发送请求,但当它恰好是POST时,它会通过发送标头来修改它(使用Content-长度)但没有实际数据。这是一个格式错误的请求,应该总是导致HTTP错误(通常在等待永远不会出现的数据超时之后)。
Microsoft将此错误记录为KB 895954(请参阅http://support.microsoft.com/kb/895954)。微软首先在IE 6中识别出这个错误。他们提供了一个修补程序,并且似乎已经随IE的每个版本发布了修补程序,包括IE 9.修复程序有两个问题:
默认情况下不会激活此修补程序。你必须使用regedit创建一个非常奇怪的密钥来激活修复程序:HKEY_LOCAL_MACHINE \ Software \ Microsoft \ Internet Explorer \ Main \ FeatureControl \ FEATURE_SKIP_POST_RETRY_ON_INTERNETWRITEFILE_KB895954。
此修复程序并未真正解决问题。 “固定”行为是在尝试发送请求时关闭连接时,它甚至不会尝试重新发送它。它只是将错误传递给javascript应用程序。
您似乎必须在代码中添加错误处理程序,并在请求失败时自行重新发布请求。我正在为我的应用程序研究这个解决方案。我担心的是,我不知道如何判断我得到的错误是由于尝试发送查询失败,还是由于查询而从服务器发回的一些错误(在这种情况下我不会想要重新发送它。)
我编写了一个C程序来模拟Web服务器并显式关闭连接以查看浏览器如何处理它。我发现IE在100%的时间内都会重现错误的行为,而Firefox,Safari和Chrome通过在100%的时间内在另一个连接上正确地重新发送POST来恢复。也许答案是,“不要使用IE浏览器。”
答案 1 :(得分:4)
作为对您问题的直接回答:是的,我们刚遇到此问题,无法找到合理的解释。它只影响IE并且频率很低 - 花了很长时间才得出结论,它是一个零星的jQuery Ajax IE漏洞。我们必须通过在这种情况下从服务器返回失败并在1秒延迟后重新发布数据来“修复”该问题!
Hacky是地狱,但似乎是唯一的方式。
肯定没有与DOM元素等发生冲突,并且没有合理的理由发生这种情况,用户可以在间歇性失败的情况下成功更新页面多次。
一定是个错误。
答案 2 :(得分:1)
我认为你必须在Internet Explorer中阻止缓存。尝试将选项缓存设置为false。
示例:
$.ajax({
url: "http://myco.com/ajaxcall.action",
data: data,
type : 'post',
dataType: 'json',
success: function(data) {},
error: function() {},
cache: false
});
答案 3 :(得分:1)
发送给PHP的params是从GET
中的IE收到的:
$.ajax ({
url: "path/to/ajax.php"
,method: "POST"
,data: {
var1: "value1"
,var2: true
,varX: 123123
}
,cache: false
,success: function (data) {
alert (data);
}
});
然后在PHP上你应该使用REQUEST而不是POST:
$var1 = $_REQUEST ["var1"]; // value1
$var2 = $_REQUEST ["var2"]; // true
$var3 = $_REQUEST ["var3"]; // 123123
此示例可以将其用于与IE7的兼容性