0

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

我发现当您的页面尝试发送 XHR 数据并且 JavaScript 冻结或延迟浏览器时,IE 延迟将 POST 数据发送到服务器。为了清楚起见,这里是重现的步骤:

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

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

在此处输入图像描述

  • 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>
4

1 回答 1

0

您正在使用同步模式,正确的是异步模式:

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

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

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

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

于 2013-07-24T13:45:05.700 回答