コンテンツにスキップ

http.serverをchromeが独占する問題と解決策

[質問]

Pythonのhttp.serverで立てたローカルWebサーバーにchromeとfirefoxでアクセスしたところ、何かのタイミングでchromeがHTTP接続を握ったままになり、セッション数の制限から、firefoxで接続できなくなります。解決策はありますか。

[回答] Grok

はい、これは Pythonの組み込みhttp.server(旧SimpleHTTPServer) を使っているときによく起こる、かなり有名な問題です。

主な原因は以下の組み合わせです:

  • http.serverシングルスレッドで動く(socketserver.TCPServerベース)
  • HTTP/1.1のpersistent connection(Keep-Alive)をデフォルトで許可している
  • Chromeが非常に積極的にKeep-Alive接続を使い続け、かつ並列リクエストを複数発行しようとする
  • 一つの接続が「読み込み待ち」の状態で開いたままになると、サーバーが新しい接続を受け付けられなくなる

結果として、Chromeが1本の接続を握り続けたままにすると、他のブラウザ(Firefoxなど)が接続できなくなる、という症状が出ます。

現実的な解決策(おすすめ順)

順位 方法 難易度 おすすめ度 備考
1 ThreadingMixIn を使う ★★☆ ★★★★★ 一番おすすめ
2 --bind 127.0.0.1 を明示 ★☆☆ ★★★★☆ 簡単だが効果は中程度
3 Chromeの「プリフェッチ/予測サービス」をオフ ★☆☆ ★★★☆☆ 根本解決ではない
4 HTTP/1.0強制(protocol_version変更) ★★☆ ★★☆☆☆ Keep-Aliveを切るが非推奨
5 http.server ではなく他のサーバーを使う ★★★★ ★★★★★ 長期的にベスト

1. 最もおすすめ:ThreadingMixIn を使う(同時接続対応)

import http.server
import socketserver

PORT = 8000

# ここがポイント
class ThreadedHTTPServer(socketserver.ThreadingMixIn, http.server.HTTPServer):
    """Handle requests in a separate thread."""
    pass

# ハンドラはそのまま
Handler = http.server.SimpleHTTPRequestHandler

# ThreadedHTTPServer を使う
with ThreadedHTTPServer(("", PORT), Handler) as httpd:
    print(f"serving at port {PORT}")
    httpd.serve_forever()

これだけで同時接続を複数処理できるようになり、Chromeが接続を握っていてもFirefoxが普通に繋がるようになります。

2. とりあえず試す価値あり(超簡単)

# Windows / macOS / Linux 共通
python -m http.server 8000 --bind 127.0.0.1

--bind 127.0.0.1 を付けると、Chromeの妙な挙動が多少マシになるケースが結構あります。

3. Chrome側の設定変更(一時しのぎ)

Chromeで
chrome://settings/privacy → 「ページのプリロード」または「予測サービスを利用してページをより速く読み込む」のチェックを外す

かなり古い問題ですが、いまだに効く環境が残っています。

まとめ(2026年現在でも有効な現実解)

一番手っ取り早く、かつ根本的に解決したいなら
ThreadingMixInを使ったサーバーを自分で書くのが最もおすすめです。

# 最小構成・おすすめ版
import http.server
import socketserver

PORT = 8000

class ThreadingSimpleServer(socketserver.ThreadingMixIn,
                           http.server.HTTPServer):
    pass

with ThreadingSimpleServer(("", PORT),
                          http.server.SimpleHTTPRequestHandler) as httpd:
    print(f"http://localhost:{PORT}")
    try:
        httpd.serve_forever()
    except KeyboardInterrupt:
        print("\nシャットダウンします")
        httpd.server_close()

これでほぼ100%解決します。

必要なら--cgiも使えるようにCGIHTTPRequestHandlerに変えたりできます。

お試しください!