jQuery JSONP 请求在 Internet Explorer 中经常失败

jQuery JSONP requests fail frequently with Internet Explorer

本文关键字:常失败 失败 请求 JSONP Internet Explorer jQuery      更新时间:2023-09-26

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

Python HTTP Server

文件夹jsonp_server包含我们的 HTTP 的简化版本名为 test_server.py 的文件中的服务器。它假设所有 GET请求是 jQuery JSONP 请求。它使用回调参数响应 JSONP 请求,该回调参数是一个 JavaScript 对象,其值为 result随机设置为 truefalse

服务器实现为 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 服务器后,您只需在 Web 浏览器中打开名为 test_01.html 的文件即可运行测试。客户端 JavaScript 位于名为 test_01.js .它只是向 HTTP 服务器发送一个 JSONP 请求 localhost每一秒。它保留请求数的计数已成功和失败的数字。这些数字是显示在浏览器中。下面列出了相应的代码:

$(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() ;
});

测试01 结果

所有测试均在运行 64 位 Windows 7 的计算机上执行终极版与服务包 1。以下浏览器在测试:

+-------------------------------+-----------------+
|           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       |
+-------------------------------+--------------+--------------+

如图所示,运行互联网时大量测试失败资源管理器,而Chrome没有失败。

知道为什么会发生这种情况吗?

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);
    }
});

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

class ThreadedHTTPServer(ThreadingMixIn, HTTPServer):
pass

测试实现中的问题将消失。