3

作为我们中型 Web 应用程序的一部分,我们利用客户端浏览器中的 jQuery 与响应 JSONP 请求的基于 Python 的 HTTP 服务器进行通信。我们注意到,在 Internet Explorer 9 或 Internet Explorer 10 中运行时,客户端代码随机无法接收来自服务器的响应。随后的测试表明,即使在使用运行在 Microsoft Windows 7 上的其他主要浏览器时,此类随机故障也会发生,但极少发生。最后,当客户端浏览器在 Linux 操作系统上运行时,没有观察到此类故障。 存储库包含我们的客户端和服务器代码的简化版本,这些代码说明了基本问题,可用于帮助调试此问题。下面用相关代码总结了它们的操作。

Python HTTP 服务器

该文件夹jsonp_server在名为test_server.py. 它假定所有 GET 请求都是 jQuery JSONP 请求。它使用回调参数响应 JSONP 请求,该回调参数是一个 JavaScript 对象,其属性名为result,其值随机设置为trueor 或false

服务器被实现为 Python 2.7 BaseHTTPServer.HTTPServer,自定义请求处理程序被实现为 BaseHTTPServer.BaseHTTPRequestHandler.

请求处理程序的do_GET()方法如下所列:

def do_GET(self):
    try:
        #
        # Send OK and content type. 
        #
        self.send_response( httplib.OK )
        self.send_header('Content-Type', 'application/json')
        self.end_headers()
        #
        # Send the JSONP response body. 
        #
        parsed_path = urlparse.urlparse(self.path)
        parsed_query = urlparse.parse_qs(parsed_path.query)
        callback = parsed_query['callback'][0]
        result = random.choice([True, False])
        self.wfile.write( "{0}({1})".format( callback, 
                                             json.dumps({ 'result' : result })) )
        return
    except IOError as errorInst:
        error_message = 'do_GET(): Internal server error while processing: {0} ({1})'.format(self.path, str(errorInst))
        self.send_error( httplib.INTERNAL_SERVER_ERROR, error_message )
        return 

测试01

文件夹下提供了一个说明问题的简单测试test_01。运行 Python HTTP 服务器后,您只需test_01.html在 Web 浏览器中打开命名的文件即可运行测试。客户端 JavaScript 位于名为 test_01.js. localhost它只是每秒钟向 HTTP 服务器发送一个 JSONP 请求 。它记录成功的请求数和失败的请求数。这些数字显示在浏览器中。对应的代码如下:

$(document).ready(function() {
    var test_count = 0 ;
    var pass_count = 0 ;
    var fail_count = 0 ;
    var test_interval_ms = 1000 ;
    var get_ajax_obj = function() {
        return {
            url: "http://localhost:8090/test_request.html", 
            timeout: 3000, 
            dataType: 'jsonp',
            success: function(data) {
                pass_count++ ;
                $('#test_result').text(data['result'] ? "True" : "False") ;
                $('#pass_count').text(pass_count) ;
                run_next_test() ;
            }, 
            error: function() {
                fail_count++ ;
                $('#fail_count').text(fail_count) ;
                run_next_test() ;
            }
        }
    } ;

    var run_next_test = function() { 
        setTimeout( function() {
            test_count++ ;
            $('#test_count').text(test_count) ;
            $.ajax(get_ajax_obj()); 
        }, test_interval_ms ) ;
    } ;

    run_next_test() ;
});

Test01 结果

所有测试均在运行带有 Service Pack 1 的 64 位 Windows 7 Ultimate 的机器上进行。测试期间使用了以下浏览器:

+-------------------------------+-----------------+
|           Browser             |     Version     |
+-------------------------------+-----------------+
| Microsoft Internet Explorer   | 10.0.9200.16721 |
| Google Chrome                 | 30.0.1599.101 m |
+-------------------------------+-----------------+

在这些测试期间的任何给定时间,只有一个浏览器在运行客户端代码。测试结果如下所示(当然,IE 结果因运行而异):

+-------------------------------+--------------+--------------+
|           Browser             |  Total Tests | Failed Tests |
+-------------------------------+--------------+--------------+
| Microsoft Internet Explorer   |    101       |     42       |
| Google Chrome                 |    150       |      0       |
+-------------------------------+--------------+--------------+

如此处所示,运行 Internet Explorer 时大量测试失败,而 Chrome 没有失败。

任何想法为什么会发生这种情况?

4

2 回答 2

0

IE 可能正在缓存结果。尝试将缓存设置为 false

$.ajax({
    url: 'http://localhost:8090/test_request.html',
    cache: false,
    dataType: 'jsonp',
    success: function(data) {
        console.log('success', data);
    },
    error: function (request, status, error) {
        console.log('error', error);
    }
});
于 2013-10-24T00:28:03.773 回答
0

尝试将您的服务器实现为多线程服务器。例如,如果您创建

class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
pass

您的测试实施中的问题将消失。

于 2015-05-18T20:19:21.733 回答