Chrome 中对本地 WSGI 服务器的 CORS AJAX 请求延迟过高

Excessive Latency on CORS AJAX Request to Local WSGI Server in Chrome

设置

两个本地 WSGI 服务器 运行 在不同的端口上。一台服务器 returns 包含 javascript 的 html 页面使用 jQuery.

向另一台 WSGI 服务器发出跨域 ajax 请求

origin_server.pyhttp://localhost:9010 为 html 服务。

#!/usr/bin/env python

from wsgiref.simple_server import make_server


def origin_html(environ, start_response):
    status = '200 OK'
    response_headers = [('Content-Type', 'text/html')]
    start_response(status, response_headers)    

    f = open('./index.html', 'rb')
    return [f.read()]

httpd = make_server('localhost', 9010, origin_html)
httpd.serve_forever()

cors_server.py 提供 javascript 将请求的跨源资源。

#!/usr/bin/env python

from wsgiref.simple_server import make_server
import json


def cors_json(environ, start_response):
    status = '200 OK'
    response_headers = [
        ('Content-Type', 'application/json'),
        ('Access-Control-Allow-Origin', '*')
    ]
    start_response(status, response_headers)

    return [json.dumps({'foo': 'bar'})]

httpd = make_server('localhost', 9011, cors_json)
httpd.serve_forever()

index.html origin_sever.py 提供的页面。

<!DOCTYPE html>
<html>
    <head>
        <script
            type="text/javascript"
            src="https://code.jquery.com/jquery-2.1.3.min.js"
            >
        </script>

        <script type="text/javascript">
            $(document).ready(function () { 
                console.log('Doing the thing.');
                $.get('http://localhost:9011').done(function (data) {
                    console.log('Got the thing', data);
                });
            });
        </script>
    </head>
    <body>
        Beep boop.
    </body>
</html>

上面 github 上的代码在这里:https://github.com/thatjpk/local-wsgi-cors-ajax

供参考的资料版本:

问题

鉴于以上情况,我可以打开两个终端,一个启动 origin_server.py,另一个启动 cors_server.py,然后打开浏览器选项卡并将其指向位于 [=26 的源服务器=].这将加载页面,并执行跨域请求。

理想情况下,延迟应该都非常低,因为它都是本地的。但是,我一直看到跨源请求的延迟超过 10 。奇怪的是我只在 Chrome 非隐身 window 中看到过这个。同一台机器上的 Firefox、curl、httpie 和 Chrome 隐身选项卡都在 10 毫秒内完成跨域请求,而非隐身 Chrome 选项卡则需要三个数量级的时间。

如果我从等式中删除 CORS,并且只是将 http://localhost:9011 放在 Chrome 地址栏中,json 会立即加载到视图中。这显然只有在请求来自 javascript.

时才会发生

如果尝试向 cors_server.py 发出另一个请求,而 Chrome 中的一个请求处于“待处理”状态,则第二个请求将等待第一个请求完成)。这意味着第一个请求在执行到达 cors_server.py.

中的处理程序之前以某种方式长时间占用 wsgi 服务器

当请求需要很长时间才能完成时,肯定会发生更多事情。我使用 tcpdump -i lo0 dst port 9011 or src port 9011.

收集了以下内容

这是来自 httpie (http get localhost:9011) 的请求,可以快速完成。

17:33:57.176028 IP localhost.64723 > localhost.9011: Flags [S], seq 2244357563, win 65535, options [mss 16344,nop,wscale 5,nop,nop,TS val 910553864 ecr 0,sackOK,eol], length 0
17:33:57.176089 IP localhost.9011 > localhost.64723: Flags [S.], seq 1494086712, ack 2244357564, win 65535, options [mss 16344,nop,wscale 5,nop,nop,TS val 910553864 ecr 910553864,sackOK,eol], length 0
17:33:57.176103 IP localhost.64723 > localhost.9011: Flags [.], ack 1, win 12759, options [nop,nop,TS val 910553864 ecr 910553864], length 0
17:33:57.176113 IP localhost.9011 > localhost.64723: Flags [.], ack 1, win 12759, options [nop,nop,TS val 910553864 ecr 910553864], length 0
17:33:57.176145 IP localhost.64723 > localhost.9011: Flags [P.], seq 1:136, ack 1, win 12759, options [nop,nop,TS val 910553864 ecr 910553864], length 135
17:33:57.176158 IP localhost.9011 > localhost.64723: Flags [.], ack 136, win 12755, options [nop,nop,TS val 910553864 ecr 910553864], length 0
17:33:57.176760 IP localhost.9011 > localhost.64723: Flags [P.], seq 1:18, ack 136, win 12755, options [nop,nop,TS val 910553864 ecr 910553864], length 17
17:33:57.176781 IP localhost.64723 > localhost.9011: Flags [.], ack 18, win 12758, options [nop,nop,TS val 910553864 ecr 910553864], length 0
17:33:57.176811 IP localhost.9011 > localhost.64723: Flags [P.], seq 18:55, ack 136, win 12755, options [nop,nop,TS val 910553864 ecr 910553864], length 37
17:33:57.176823 IP localhost.64723 > localhost.9011: Flags [.], ack 55, win 12757, options [nop,nop,TS val 910553864 ecr 910553864], length 0
17:33:57.176834 IP localhost.9011 > localhost.64723: Flags [P.], seq 55:92, ack 136, win 12755, options [nop,nop,TS val 910553864 ecr 910553864], length 37
17:33:57.176844 IP localhost.64723 > localhost.9011: Flags [.], ack 92, win 12756, options [nop,nop,TS val 910553864 ecr 910553864], length 0
17:33:57.176857 IP localhost.9011 > localhost.64723: Flags [P.], seq 92:178, ack 136, win 12755, options [nop,nop,TS val 910553864 ecr 910553864], length 86
17:33:57.176866 IP localhost.64723 > localhost.9011: Flags [.], ack 178, win 12753, options [nop,nop,TS val 910553864 ecr 910553864], length 0
17:33:57.176878 IP localhost.9011 > localhost.64723: Flags [P.], seq 178:192, ack 136, win 12755, options [nop,nop,TS val 910553864 ecr 910553864], length 14
17:33:57.176886 IP localhost.64723 > localhost.9011: Flags [.], ack 192, win 12753, options [nop,nop,TS val 910553864 ecr 910553864], length 0
17:33:57.176961 IP localhost.9011 > localhost.64723: Flags [F.], seq 192, ack 136, win 12755, options [nop,nop,TS val 910553865 ecr 910553864], length 0
17:33:57.176975 IP localhost.64723 > localhost.9011: Flags [.], ack 193, win 12753, options [nop,nop,TS val 910553865 ecr 910553865], length 0
17:33:57.176980 IP localhost.9011 > localhost.64723: Flags [.], ack 136, win 12755, options [nop,nop,TS val 910553865 ecr 910553865], length 0
17:33:57.182034 IP localhost.64723 > localhost.9011: Flags [F.], seq 136, ack 193, win 12753, options [nop,nop,TS val 910553870 ecr 910553865], length 0
17:33:57.182095 IP localhost.9011 > localhost.64723: Flags [.], ack 137, win 12755, options [nop,nop,TS val 910553870 ecr 910553870], length 0

这是来自 Firefox 的请求,可以快速完成。

18:12:57.416741 IP localhost.65089 > localhost.9011: Flags [S], seq 2202457533, win 65535, options [mss 16344,nop,wscale 5,nop,nop,TS val 912890306 ecr 0,sackOK,eol], length 0
18:12:57.416794 IP localhost.9011 > localhost.65089: Flags [S.], seq 1807873905, ack 2202457534, win 65535, options [mss 16344,nop,wscale 5,nop,nop,TS val 912890306 ecr 912890306,sackOK,eol], length 0
18:12:57.416806 IP localhost.65089 > localhost.9011: Flags [.], ack 1, win 12759, options [nop,nop,TS val 912890306 ecr 912890306], length 0
18:12:57.416818 IP localhost.9011 > localhost.65089: Flags [.], ack 1, win 12759, options [nop,nop,TS val 912890306 ecr 912890306], length 0
18:12:57.416883 IP localhost.65089 > localhost.9011: Flags [P.], seq 1:346, ack 1, win 12759, options [nop,nop,TS val 912890306 ecr 912890306], length 345
18:12:57.416899 IP localhost.9011 > localhost.65089: Flags [.], ack 346, win 12748, options [nop,nop,TS val 912890306 ecr 912890306], length 0
18:12:57.417478 IP localhost.9011 > localhost.65089: Flags [P.], seq 1:18, ack 346, win 12748, options [nop,nop,TS val 912890306 ecr 912890306], length 17
18:12:57.417492 IP localhost.65089 > localhost.9011: Flags [.], ack 18, win 12758, options [nop,nop,TS val 912890306 ecr 912890306], length 0
18:12:57.417516 IP localhost.9011 > localhost.65089: Flags [P.], seq 18:55, ack 346, win 12748, options [nop,nop,TS val 912890306 ecr 912890306], length 37
18:12:57.417538 IP localhost.65089 > localhost.9011: Flags [.], ack 55, win 12757, options [nop,nop,TS val 912890306 ecr 912890306], length 0
18:12:57.417548 IP localhost.9011 > localhost.65089: Flags [P.], seq 55:92, ack 346, win 12748, options [nop,nop,TS val 912890306 ecr 912890306], length 37
18:12:57.417555 IP localhost.65089 > localhost.9011: Flags [.], ack 92, win 12756, options [nop,nop,TS val 912890306 ecr 912890306], length 0
18:12:57.417562 IP localhost.9011 > localhost.65089: Flags [P.], seq 92:192, ack 346, win 12748, options [nop,nop,TS val 912890306 ecr 912890306], length 100
18:12:57.417569 IP localhost.65089 > localhost.9011: Flags [.], ack 192, win 12753, options [nop,nop,TS val 912890306 ecr 912890306], length 0
18:12:57.417618 IP localhost.9011 > localhost.65089: Flags [F.], seq 192, ack 346, win 12748, options [nop,nop,TS val 912890306 ecr 912890306], length 0
18:12:57.417629 IP localhost.65089 > localhost.9011: Flags [.], ack 193, win 12753, options [nop,nop,TS val 912890306 ecr 912890306], length 0
18:12:57.417634 IP localhost.9011 > localhost.65089: Flags [.], ack 346, win 12748, options [nop,nop,TS val 912890306 ecr 912890306], length 0
18:12:57.417638 IP localhost.65089 > localhost.9011: Flags [F.], seq 346, ack 193, win 12753, options [nop,nop,TS val 912890306 ecr 912890306], length 0
18:12:57.417647 IP localhost.9011 > localhost.65089: Flags [.], ack 347, win 12748, options [nop,nop,TS val 912890306 ecr 912890306], length 0

这是来自 Chrome 隐身标签的请求,可以快速完成。

17:28:10.096905 IP6 localhost.64691 > localhost.9011: Flags [S], seq 2861078667, win 65535, options [mss 16324,nop,wscale 5,nop,nop,TS val 910207638 ecr 0,sackOK,eol], length 0
17:28:10.096926 IP6 localhost.9011 > localhost.64691: Flags [R.], seq 0, ack 2861078668, win 0, length 0
17:28:10.097010 IP localhost.64692 > localhost.9011: Flags [S], seq 3615577823, win 65535, options [mss 16344,nop,wscale 5,nop,nop,TS val 910207638 ecr 0,sackOK,eol], length 0
17:28:10.097056 IP localhost.9011 > localhost.64692: Flags [S.], seq 3533709271, ack 3615577824, win 65535, options [mss 16344,nop,wscale 5,nop,nop,TS val 910207638 ecr 910207638,sackOK,eol], length 0
17:28:10.097066 IP localhost.64692 > localhost.9011: Flags [.], ack 1, win 12759, options [nop,nop,TS val 910207638 ecr 910207638], length 0
17:28:10.097075 IP localhost.9011 > localhost.64692: Flags [.], ack 1, win 12759, options [nop,nop,TS val 910207638 ecr 910207638], length 0
17:28:10.097274 IP localhost.64692 > localhost.9011: Flags [P.], seq 1:373, ack 1, win 12759, options [nop,nop,TS val 910207638 ecr 910207638], length 372
17:28:10.097293 IP localhost.9011 > localhost.64692: Flags [.], ack 373, win 12747, options [nop,nop,TS val 910207638 ecr 910207638], length 0
17:28:10.098108 IP localhost.9011 > localhost.64692: Flags [P.], seq 1:18, ack 373, win 12747, options [nop,nop,TS val 910207639 ecr 910207638], length 17
17:28:10.098131 IP localhost.64692 > localhost.9011: Flags [.], ack 18, win 12758, options [nop,nop,TS val 910207639 ecr 910207639], length 0
17:28:10.098166 IP localhost.9011 > localhost.64692: Flags [P.], seq 18:55, ack 373, win 12747, options [nop,nop,TS val 910207639 ecr 910207639], length 37
17:28:10.098184 IP localhost.64692 > localhost.9011: Flags [.], ack 55, win 12757, options [nop,nop,TS val 910207639 ecr 910207639], length 0
17:28:10.098212 IP localhost.9011 > localhost.64692: Flags [P.], seq 55:92, ack 373, win 12747, options [nop,nop,TS val 910207639 ecr 910207639], length 37
17:28:10.098232 IP localhost.64692 > localhost.9011: Flags [.], ack 92, win 12756, options [nop,nop,TS val 910207639 ecr 910207639], length 0
17:28:10.098246 IP localhost.9011 > localhost.64692: Flags [P.], seq 92:178, ack 373, win 12747, options [nop,nop,TS val 910207639 ecr 910207639], length 86
17:28:10.098267 IP localhost.64692 > localhost.9011: Flags [.], ack 178, win 12753, options [nop,nop,TS val 910207639 ecr 910207639], length 0
17:28:10.098277 IP localhost.9011 > localhost.64692: Flags [P.], seq 178:192, ack 373, win 12747, options [nop,nop,TS val 910207639 ecr 910207639], length 14
17:28:10.098283 IP localhost.64692 > localhost.9011: Flags [.], ack 192, win 12753, options [nop,nop,TS val 910207639 ecr 910207639], length 0
17:28:10.098352 IP localhost.9011 > localhost.64692: Flags [F.], seq 192, ack 373, win 12747, options [nop,nop,TS val 910207639 ecr 910207639], length 0
17:28:10.098369 IP localhost.64692 > localhost.9011: Flags [.], ack 193, win 12753, options [nop,nop,TS val 910207639 ecr 910207639], length 0
17:28:10.098380 IP localhost.9011 > localhost.64692: Flags [.], ack 373, win 12747, options [nop,nop,TS val 910207639 ecr 910207639], length 0
17:28:10.099183 IP localhost.64692 > localhost.9011: Flags [F.], seq 373, ack 193, win 12753, options [nop,nop,TS val 910207640 ecr 910207639], length 0
17:28:10.099217 IP localhost.9011 > localhost.64692: Flags [.], ack 374, win 12747, options [nop,nop,TS val 910207640 ecr 910207640], length 0

这是来自常规 Chrome 选项卡的请求,耗时约 18 秒。

17:28:27.147218 IP6 localhost.64699 > localhost.9011: Flags [S], seq 1481186887, win 65535, options [mss 16324,nop,wscale 5,nop,nop,TS val 910224643 ecr 0,sackOK,eol], length 0
17:28:27.147230 IP6 localhost.9011 > localhost.64699: Flags [R.], seq 0, ack 1481186888, win 0, length 0
17:28:27.147277 IP6 localhost.64700 > localhost.9011: Flags [S], seq 1928824698, win 65535, options [mss 16324,nop,wscale 5,nop,nop,TS val 910224643 ecr 0,sackOK,eol], length 0
17:28:27.147287 IP6 localhost.9011 > localhost.64700: Flags [R.], seq 0, ack 1928824699, win 0, length 0
17:28:27.147331 IP6 localhost.64701 > localhost.9011: Flags [S], seq 63463797, win 65535, options [mss 16324,nop,wscale 5,nop,nop,TS val 910224643 ecr 0,sackOK,eol], length 0
17:28:27.147340 IP6 localhost.9011 > localhost.64701: Flags [R.], seq 0, ack 63463798, win 0, length 0
17:28:27.147578 IP localhost.64704 > localhost.9011: Flags [S], seq 2185396531, win 65535, options [mss 16344,nop,wscale 5,nop,nop,TS val 910224643 ecr 0,sackOK,eol], length 0
17:28:27.147602 IP localhost.64705 > localhost.9011: Flags [S], seq 2307844059, win 65535, options [mss 16344,nop,wscale 5,nop,nop,TS val 910224643 ecr 0,sackOK,eol], length 0
17:28:27.147617 IP localhost.9011 > localhost.64704: Flags [S.], seq 4199967470, ack 2185396532, win 65535, options [mss 16344,nop,wscale 5,nop,nop,TS val 910224643 ecr 910224643,sackOK,eol], length 0
17:28:27.147627 IP localhost.64706 > localhost.9011: Flags [S], seq 324888549, win 65535, options [mss 16344,nop,wscale 5,nop,nop,TS val 910224643 ecr 0,sackOK,eol], length 0
17:28:27.147638 IP localhost.9011 > localhost.64705: Flags [S.], seq 1097272416, ack 2307844060, win 65535, options [mss 16344,nop,wscale 5,nop,nop,TS val 910224643 ecr 910224643,sackOK,eol], length 0
17:28:27.147643 IP localhost.64704 > localhost.9011: Flags [.], ack 1, win 12759, options [nop,nop,TS val 910224643 ecr 910224643], length 0
17:28:27.147665 IP localhost.9011 > localhost.64706: Flags [S.], seq 837656804, ack 324888550, win 65535, options [mss 16344,nop,wscale 5,nop,nop,TS val 910224643 ecr 910224643,sackOK,eol], length 0
17:28:27.147669 IP localhost.64705 > localhost.9011: Flags [.], ack 1, win 12759, options [nop,nop,TS val 910224643 ecr 910224643], length 0
17:28:27.147675 IP localhost.9011 > localhost.64704: Flags [.], ack 1, win 12759, options [nop,nop,TS val 910224643 ecr 910224643], length 0
17:28:27.147681 IP localhost.64706 > localhost.9011: Flags [.], ack 1, win 12759, options [nop,nop,TS val 910224643 ecr 910224643], length 0
17:28:27.147686 IP localhost.9011 > localhost.64705: Flags [.], ack 1, win 12759, options [nop,nop,TS val 910224643 ecr 910224643], length 0
17:28:27.147691 IP localhost.9011 > localhost.64706: Flags [.], ack 1, win 12759, options [nop,nop,TS val 910224643 ecr 910224643], length 0
17:28:27.243730 IP6 localhost.64708 > localhost.9011: Flags [S], seq 4213763930, win 65535, options [mss 16324,nop,wscale 5,nop,nop,TS val 910224733 ecr 0,sackOK,eol], length 0
17:28:27.243748 IP6 localhost.9011 > localhost.64708: Flags [R.], seq 0, ack 4213763931, win 0, length 0
17:28:27.243855 IP localhost.64709 > localhost.9011: Flags [S], seq 1721904940, win 65535, options [mss 16344,nop,wscale 5,nop,nop,TS val 910224733 ecr 0,sackOK,eol], length 0
17:28:27.243910 IP localhost.9011 > localhost.64709: Flags [S.], seq 2521348026, ack 1721904941, win 65535, options [mss 16344,nop,wscale 5,nop,nop,TS val 910224733 ecr 910224733,sackOK,eol], length 0
17:28:27.243925 IP localhost.64709 > localhost.9011: Flags [.], ack 1, win 12759, options [nop,nop,TS val 910224733 ecr 910224733], length 0
17:28:27.243934 IP localhost.9011 > localhost.64709: Flags [.], ack 1, win 12759, options [nop,nop,TS val 910224733 ecr 910224733], length 0
17:28:27.244093 IP localhost.64709 > localhost.9011: Flags [P.], seq 1:390, ack 1, win 12759, options [nop,nop,TS val 910224733 ecr 910224733], length 389
17:28:27.244108 IP localhost.9011 > localhost.64709: Flags [.], ack 390, win 12747, options [nop,nop,TS val 910224733 ecr 910224733], length 0
17:28:45.693569 IP localhost.64704 > localhost.9011: Flags [F.], seq 1, ack 1, win 12759, options [nop,nop,TS val 910243145 ecr 910224643], length 0
17:28:45.693596 IP localhost.64705 > localhost.9011: Flags [F.], seq 1, ack 1, win 12759, options [nop,nop,TS val 910243145 ecr 910224643], length 0
17:28:45.693605 IP localhost.64706 > localhost.9011: Flags [F.], seq 1, ack 1, win 12759, options [nop,nop,TS val 910243145 ecr 910224643], length 0
17:28:45.693627 IP localhost.9011 > localhost.64704: Flags [.], ack 2, win 12759, options [nop,nop,TS val 910243145 ecr 910243145], length 0
17:28:45.693636 IP localhost.9011 > localhost.64705: Flags [.], ack 2, win 12759, options [nop,nop,TS val 910243145 ecr 910243145], length 0
17:28:45.693645 IP localhost.9011 > localhost.64706: Flags [.], ack 2, win 12759, options [nop,nop,TS val 910243145 ecr 910243145], length 0
17:28:45.693655 IP localhost.64704 > localhost.9011: Flags [.], ack 1, win 12759, options [nop,nop,TS val 910243145 ecr 910243145], length 0
17:28:45.693661 IP localhost.64705 > localhost.9011: Flags [.], ack 1, win 12759, options [nop,nop,TS val 910243145 ecr 910243145], length 0
17:28:45.693666 IP localhost.64706 > localhost.9011: Flags [.], ack 1, win 12759, options [nop,nop,TS val 910243145 ecr 910243145], length 0
17:28:45.693737 IP localhost.9011 > localhost.64704: Flags [F.], seq 1, ack 2, win 12759, options [nop,nop,TS val 910243145 ecr 910243145], length 0
17:28:45.693766 IP localhost.64704 > localhost.9011: Flags [.], ack 2, win 12759, options [nop,nop,TS val 910243145 ecr 910243145], length 0
17:28:45.693862 IP localhost.9011 > localhost.64705: Flags [F.], seq 1, ack 2, win 12759, options [nop,nop,TS val 910243145 ecr 910243145], length 0
17:28:45.693909 IP localhost.64705 > localhost.9011: Flags [.], ack 2, win 12759, options [nop,nop,TS val 910243145 ecr 910243145], length 0
17:28:45.693935 IP localhost.9011 > localhost.64706: Flags [F.], seq 1, ack 2, win 12759, options [nop,nop,TS val 910243145 ecr 910243145], length 0
17:28:45.693949 IP localhost.64706 > localhost.9011: Flags [.], ack 2, win 12759, options [nop,nop,TS val 910243145 ecr 910243145], length 0
17:28:45.694861 IP localhost.9011 > localhost.64709: Flags [P.], seq 1:18, ack 390, win 12747, options [nop,nop,TS val 910243146 ecr 910224733], length 17
17:28:45.694886 IP localhost.64709 > localhost.9011: Flags [.], ack 18, win 12758, options [nop,nop,TS val 910243146 ecr 910243146], length 0
17:28:45.694937 IP localhost.9011 > localhost.64709: Flags [P.], seq 18:55, ack 390, win 12747, options [nop,nop,TS val 910243146 ecr 910243146], length 37
17:28:45.694958 IP localhost.64709 > localhost.9011: Flags [.], ack 55, win 12757, options [nop,nop,TS val 910243146 ecr 910243146], length 0
17:28:45.694971 IP localhost.9011 > localhost.64709: Flags [P.], seq 55:92, ack 390, win 12747, options [nop,nop,TS val 910243146 ecr 910243146], length 37
17:28:45.694982 IP localhost.64709 > localhost.9011: Flags [.], ack 92, win 12756, options [nop,nop,TS val 910243146 ecr 910243146], length 0
17:28:45.694997 IP localhost.9011 > localhost.64709: Flags [P.], seq 92:178, ack 390, win 12747, options [nop,nop,TS val 910243146 ecr 910243146], length 86
17:28:45.695009 IP localhost.64709 > localhost.9011: Flags [.], ack 178, win 12753, options [nop,nop,TS val 910243146 ecr 910243146], length 0
17:28:45.695016 IP localhost.9011 > localhost.64709: Flags [P.], seq 178:192, ack 390, win 12747, options [nop,nop,TS val 910243146 ecr 910243146], length 14
17:28:45.695020 IP localhost.64709 > localhost.9011: Flags [.], ack 192, win 12753, options [nop,nop,TS val 910243146 ecr 910243146], length 0
17:28:45.695087 IP localhost.9011 > localhost.64709: Flags [F.], seq 192, ack 390, win 12747, options [nop,nop,TS val 910243146 ecr 910243146], length 0
17:28:45.695111 IP localhost.64709 > localhost.9011: Flags [.], ack 193, win 12753, options [nop,nop,TS val 910243146 ecr 910243146], length 0
17:28:45.695120 IP localhost.9011 > localhost.64709: Flags [.], ack 390, win 12747, options [nop,nop,TS val 910243146 ecr 910243146], length 0
17:28:45.696046 IP localhost.64709 > localhost.9011: Flags [F.], seq 390, ack 193, win 12753, options [nop,nop,TS val 910243147 ecr 910243146], length 0
17:28:45.696069 IP localhost.9011 > localhost.64709: Flags [.], ack 391, win 12747, options [nop,nop,TS val 910243147 ecr 910243147], length 0

看起来 Chrome 首先尝试 IPv6,wsgiref 不喜欢。所以连接重置服务器发送是有意义的。

在非隐身 Chrome 的情况下,客户端似乎进行了多次连接尝试。服务器重置前几次尝试,然后接受几次,然后客户端仅使用其中一个连接实际发送请求。我假设因为 wsgiref.simple_server 是单线程的,所以之前的连接必须超时才能处理实际请求;因此延迟。

有趣的是,即使隐身 Chrome 仍然会遇到重置,但只是重试一次,然后按预期工作。 Firefox 和 httpie 都只建立一个顺利工作的单一连接。

问题

我相信您也在从服务器读取元数据。检查您提出的请求的日志。

tl;dr:Chrome 优化过于激进。 11 点新闻。


原来这是因为 "optimization" Chrome 确实可以加快页面加载、API 交互等

Chrome 有一个名为 "Predict network actions to improve page load performance" 的设置。 (它在高级设置中的隐私下。)当启用此功能时,Chrome 将抢先打开与托管页面资源的服务器的 TCP 连接,甚至在客户端代码到达将告诉浏览器的执行点之前发出 HTTP 请求。

在这种情况下,Chrome 发现我将向 CORS 服务器发出 AJAX 请求,并打开到服务器的多个 TCP 连接,为我可能发出的其他 HTTP 请求做准备稍后(即使我的 javascript 只会向服务器发出一个请求)。它显然在 之前 打开这些额外的连接,这些连接实际上将承载 javascript 将发出的一个 HTTP 请求。这意味着对于单线程服务器,那些额外的连接必须在承载请求的连接得到服务之前超时。这就是延迟的根源。

"Predict network actions to improve page load performance" 设置在默认情况下处于启用状态,并且在隐身时处于非活动状态(大概是因为它会将用户的行为泄露给可能会或可能不会最终收到请求的服务器)。禁用它可以防止打开这些额外的连接,并且 Chrome 在这种情况下的行为与 Firefox 相同。

这让我想知道有多少 TCP 连接 Chrome 在 Internet 上的生产服务器上打开,这些连接要么未被使用,要么在发送请求之前保持打开状态的时间过长。未使用的连接甚至不会显示在访问日志中,因为没有发出 HTTP 请求,因此很难衡量 Chrome 用户创建了多少额外负载。在我看来,这种行为是有害的。首先,因为它试图提高客户端性能(这是令人钦佩的),但这样做是以牺牲服务器操作员为代价的(事实并非如此)。其次,因为(因为它在隐身模式下被禁用而被避免)对隐私有负面影响。