最近,我发现在发送XHR数据时IE8 / 9的行为非常奇怪。我想问你是否见过这样的行为?这是IE漏洞吗?如何保护我的服务器免受IE生成的“空”请求?以下是更多细节:
我发现当您的页面尝试发送XHR数据并且JavaScript冻结或滞后浏览器时,IE会滞后将POST数据发送到服务器。为了说清楚,以下是重现的步骤:
创建转储收到的POST的简单服务器。我已经使用Node.JS进行测试。您可以在帖子底部找到相应的代码。
在IE中打开localhost:8080,打开调试窗口并开始使用在文件localhost:8080
的第51行设置的断点来调试脚本
点击Send by JQuery
。您应该让您的javascript等待断点和服务器记录消息:
--------------------------------------
14:04:19
REQUEST: /
HTTP HEADER:
accept = text/html, application/xhtml+xml, */*
accept-language = pl-PL
user-agent = Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)
accept-encoding = gzip, deflate
host = localhost:8080
connection = Keep-Alive
--------------------------------------
14:04:35
REQUEST: /test
HTTP HEADER:
accept = */*
content-type = application/json
x-requested-with = XMLHttpRequest
referer = http://localhost:8080/
accept-language = pl
accept-encoding = gzip, deflate
user-agent = Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; WOW64; Trident/5.0)
host = localhost:8080
content-length = 24
connection = Keep-Alive
cache-control = no-cache
从断点服务器发布JavaScript时,按新行报告传入数据:
POST: {"data1":10,"data2":123}
我在Opera 12.15和Chrome 27.0.1453.94 m上完成了相同的测试,正如预期的那样,会立即发送POST数据。
- 源代码 -
node.js服务器的代码:
var http = require('http');
var qs = require('querystring');
var fs = require('fs');
http.createServer(function (req, res) {
console.log('--------------------------------------');
console.log(new Date().toLocaleTimeString());
console.log('REQUEST: ' + req.url);
console.log('HTTP HEADER: ');
for (var header in req.headers) {
console.log(' ' + header + ' = ' + req.headers[header]);
}
switch (req.method) {
case 'POST':
var body = '';
req.on('data', function (data) {
body += data;
});
req.on('end', function() {
console.log('POST: ' + body);
});
res.writeHead(200, {'Content-type': 'application/json'});
res.end(JSON.stringify({ succeeded: true, value: 'Hello world!' }));
break;
case 'GET':
fs.readFile('./servertest.html', function (err, data) {
if (err) {
throw err;
}
res.writeHeader(200, {'Content-type': 'text/html'});
res.end(data);
});
break;
}
}).listen(8080, 'localhost');
console.log('listening on localhost:8080');
servertest.html的代码:
<!DOCTYPE html>
<html>
<head>
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"></script>
</head>
<body>
<button onclick="send()">Send by JQuery</button>
<button onclick="sendXHR()">Send by XHR</button>
</body>
<script type="text/javascript">
var _xhr;
function sendXHR() {
_xhr = new XMLHttpRequest();
new XHRStateChangeListener();
var url = '/testXHR';
var method = 'POST';
_xhr.open(method, url);
_xhr.setRequestHeader("Content-Type", "application/json");
_xhr.send(JSON.stringify({test: 'this is a test', aoawiejf:23423}));
}
function XHRStateChangeListener() {
callback = function() {
var msg;
if (_xhr.readyState == 4 && /200|304/.test(_xhr.status)) {
alert('ready: ' + _xhr.responseText);
}
};
_xhr.onreadystatechange = callback;
}
function send() {
$.ajax({
url: '/test',
type: 'POST',
data: JSON.stringify({data1: 10, data2: 123}),
contentType: 'application/json',
error: function(xhr, status, err) {
alert('Error: ' + err + '\nStatus: ' + status);
},
success: function (data) {
alert('succeeded! data: ' + data);
}
});
}
</script>
</html>
答案 0 :(得分:0)
您正在使用同步模式,右侧是异步模式:
替换
_xhr.open(method, url);
通过
_xhr.open(method, url, true);//Async mode
注意:请记住“onreadystatechange”仅适用于异步模式
问题也可能出在这个函数中(只是一个猜测):
JSON.stringify
尝试发送空数据,即:data:""