简单的Python服务器 - 如何防止在两端发送304?

-1 投票
1 回答
49 浏览
提问于 2025-04-13 14:03

我在Windows上用Python搭建了一个简单的本地HTTP服务器。

我创建了一个HTML文件,里面有JavaScript代码,使用setInterval()每秒请求一次本地目录中的JSON文件。(然后用获取到的JSON内容更新网页。)

这很好用,直到大约15到60秒后,浏览器停止发送请求,根据终端中的服务器日志显示,响应状态码304总是在中断之前出现。

我该怎么做才能避免这种情况,让服务器每秒都能提供JSON文件呢?

我对这个尝试非常陌生,之前还得做一些小技巧才能让浏览器请求本地的JSON文件,因为安全协议的限制。这也是为什么需要搭建服务器,因为通过file:///是无法做到的。

我在想,能不能在服务器上做些改动,让它在想要返回304时,实际返回200。我希望如果总是返回200,浏览器就不会暂停请求。

我还有一个想法,就是确保JSON文件的内容总是变化,这样就能避免被缓存的情况。

1 个回答

0

看起来你的问题和缓存有关。浏览器从服务器收到了一个304的响应,这意味着自上次请求以来,内容没有被修改,所以它选择使用缓存中的版本,而不是重新请求。

如果你想强制浏览器每次都从服务器获取JSON文件,而不是使用缓存,你可以尝试在服务器端禁用缓存。你可以修改你的Python HTTP服务器,添加一些头信息来防止缓存。具体来说,可以把Cache-Control头设置为no-cache。

import sys
from http.server import HTTPServer, SimpleHTTPRequestHandler, test


class CORSRequestHandler(SimpleHTTPRequestHandler):
    def end_headers(self):
        self.send_header('Access-Control-Allow-Origin', '*')
        self.send_header('Cache-Control', 'no-cache')
        SimpleHTTPRequestHandler.end_headers(self)


if __name__ == '__main__':
    test(CORSRequestHandler, HTTPServer, port=int(sys.argv[1]) if len(sys.argv) > 1 else 8000)

根据我的理解,代码大概是这样的:

main.py
import os
import sys
from http.server import HTTPServer, SimpleHTTPRequestHandler


class CORSRequestHandler(SimpleHTTPRequestHandler):
    def end_headers(self):
        self.send_header('Access-Control-Allow-Origin', '*')
        self.send_header('Cache-Control', 'no-cache')
        super().end_headers()

    def do_GET(self):
        if self.path == '/data.json':
            self.send_response(200)
            self.send_header('Content-type', 'application/json')
            self.end_headers()
            with open(os.path.join(os.getcwd(), 'data.json'), 'rb') as file:
                self.wfile.write(file.read())
        else:
            super().do_GET()


def run_server(port):
    server_address = ('', port)
    httpd = HTTPServer(server_address, CORSRequestHandler)
    print(f"Server running on port {port}")
    httpd.serve_forever()


if __name__ == '__main__':
    port = int(sys.argv[1]) if len(sys.argv) > 1 else 8000
    run_server(port)

index.html

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>JSON</title>
</head>
<body>
    <h1>JSON</h1>
    <div id="my-content"></div>
    <script>
        function fetchData() {
            fetch('http://localhost:8000/data.json')
                .then(response => response.json())
                .then(data => {
                    document.getElementById('my-content').innerText = JSON.stringify(data, null, 2);
                })
                .catch(error => console.error('Error fetching data:', error));
        }

        setInterval(fetchData, 1000);
    </script>
</body>
</html>

撰写回答