我注意到Safari 5.0.5(6533.21.1)似乎正在提交重复的ajax调用。当我运行以下简化测试用例时:
// jquery 1.6 include
$(document).ready(function() {
setTimeout(function(e) {
var req1 = $.getJSON('/api/private/customers.json');
console.log('req1 sent');
}, 2000);
setTimeout(function(e) {
var req2 = $.getJSON('/api/private/customers.json');
console.log('req1 sent');
}, 4000);
});
Safari资源面板和控制台显示两个xhr请求,但我的服务器日志显示三个xhr请求:
XX.XX.XX.XXX - - [10/May/2011:16:50:40 -0400] "GET /api/private/customers.json HTTP/1.1" 200 183 "https://sub.mydomain.com/customers" "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_7; en-us) AppleWebKit/533.21.1 (KHTML, like Gecko) Version/5.0.5 Safari/533.21.1"
XX.XX.XX.XXX - - [10/May/2011:16:50:42 -0400] "GET /api/private/customers.json HTTP/1.1" 200 183 "https://sub.mydomain.com/customers" "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_7; en-us) AppleWebKit/533.21.1 (KHTML, like Gecko) Version/5.0.5 Safari/533.21.1"
XX.XX.XX.XXX - - [10/May/2011:16:50:42 -0400] "GET /api/private/customers.json HTTP/1.1" 200 183 "https://sub.mycomain.com/customers" "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_7; en-us) AppleWebKit/533.21.1 (KHTML, like Gecko) Version/5.0.5 Safari/533.21.1"
当我使用最新版本的Firefox发出相同的请求时,我正确地收到了两个请求:
XX.XX.XX.XXX - - [10/May/2011:16:52:00 -0400] "GET /api/private/customers.json HTTP/1.1" 200 183 "https://sub.mycomain.com/customers" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:2.0.1) Gecko/20100101 Firefox/4.0.1"
XX.XX.XX.XXX - - [10/May/2011:16:52:02 -0400] "GET /api/private/customers.json HTTP/1.1" 200 183 "https://sub.mycomain.com/customers" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:2.0.1) Gecko/20100101 Firefox/4.0.1"
第一个请求似乎没有发生此行为,但所有后续请求都是一式两份发送的。有谁知道发生了什么事?在js中检测额外请求的努力是徒劳的。
答案 0 :(得分:3)
我想我们不会知道这是一个错误还是一个功能......无论如何,Safari(在10.0.2版本中)仍然按照conditionnal request的说明执行Dan Manastireanu。
我发现请求不重复的方法是使用当前请求时间设置'If-Unmodified-Since'
标头。
(或者您也可以在网址中添加时间戳参数,Dan Manastireanu再次提及)
我对setRequestHeader('Connection', "close")
进行了投票,因为它是forbidden header name并抛出Refused to set unsafe header "Connection"
错误。
所以基本请求如下:
var get = function(url, callbackSucess, callbackError) {
var request = new XMLHttpRequest();
request.open('GET', url, true);
request.timeout = 10000;
var now = new Date().getTime();
request.setRequestHeader('If-Unmodified-Since', now);
request.onreadystatechange = function() {
if (request.readyState !== 4) {
return;
}
if (request.status === 200) {
callbackSucess(request.status);
} else {
callbackError(request.status);
}
};
request.onerror = function (error) {
callbackError(error);
};
request.ontimeout = function () {
request.abort();
};
request.send(null);
}
答案 1 :(得分:2)
我认为浏览器正在为第二个电话拨打conditional GET request(另请参阅304 response status)。
在第一次调用时,浏览器中没有缓存响应,因此它会执行正常请求 在第二个请求中,浏览器首先执行条件GET请求,并且在看到其缓存的响应已过期时,它必须重复GET请求。
据我所知,jQuery有一个内置的修复程序(它自动将一个参数附加到请求URL,类似_=123456789
)。我不知道为什么这不起作用。
您可以尝试手动附加请求参数:'/api/private/customers.json?v='+(new Date().getTime())
或者您可以尝试将jQuery.ajax
与cache:false
和dataType:'jsonp'
您可以打开Safari的开发人员工具(Web Inspector),然后查看“网络”选项卡。它会告诉您有关请求和响应的更多信息。
答案 2 :(得分:1)
在API响应中添加连接:关闭标头可以解决问题。