IE在发送POST数据方面滞后

时间:2013-06-04 12:24:36

标签: ajax internet-explorer jquery xmlhttprequest

最近,我发现在发送XHR数据时IE8 / 9的行为非常奇怪。我想问你是否见过这样的行为?这是IE漏洞吗?如何保护我的服务器免受IE生成的“空”请求?以下是更多细节:

我发现当您的页面尝试发送XHR数据并且JavaScript冻结或滞后浏览器时,IE会滞后将POST数据发送到服务器。为了说清楚,以下是重现的步骤:

  • 创建转储收到的POST的简单服务器。我已经使用Node.JS进行测试。您可以在帖子底部找到相应的代码。

  • 在IE中打开localhost:8080,打开调试窗口并开始使用在文件localhost:8080的第51行设置的断点来调试脚本

enter image description here

  • 点击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>

1 个答案:

答案 0 :(得分:0)

您正在使用同步模式,右侧是异步模式:

替换 _xhr.open(method, url); 通过 _xhr.open(method, url, true);//Async mode

  

注意:请记住“onreadystatechange”仅适用于异步模式

问题也可能出在这个函数中(只是一个猜测): JSON.stringify

尝试发送空数据,即:data:""