pythonjsonhttpstatus

Simple Python Server - How to prevent sending 304 on either end?


I set up a local simple http server in python on windows.

I set up an HTML file with javascript that uses setInterval() to request a JSON in the local directory every second. (Then updates the webpage with json content.)

Great, this works. Until after 15-60 seconds, the browser stops making requests, based on the server log in the terminal. The response 304 always precedes the break.

How can I avoid this and force the server always serve the json file every second?

Very new to this attempt and had to do tricks to make the browser even make the requests for local jsons or so due to security protocols. In part why the server is necessary, as via file:/// it can't be done.

My thought is change something in the server so if it wants to respond with 304, it will give a 200. I hope if it's always 200, the browser won't pause requests.

My other thought is ensure the json is always changing, hopefully avoiding the idea of it cached.


Solution

  • It seems like your issue is related to caching. The browser is receiving a 304 response from the server, indicating that the content has not been modified since the last request, so it's using the cached version instead of making a new request.

    To force the browser to always fetch the JSON file from the server instead of using the cache, you can try to disable caching on the server side. You can modify your Python HTTP server to include headers that prevent caching. You can do this by setting the Cache-Control headers to 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)
    

    In my understanding it looks something like this: 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>