How to build an offline web app using Flask?
Asked Answered
S

1

5

I'm prototyping an idea for a website that will use the HTML5 offline application cache for certain purposes. The website will be built with Python and Flask and that's where my main problem comes from: I'm working with those two for the first time, so I'm having a hard time getting the manifest file to work as expected.

The issue is that I'm getting 404's from the static files included in the manifest file. The manifest itself seems to be downloaded correctly, but the files that it points to are not. This is what is spit out in the console when loading the page:

Creating Application Cache with manifest http://127.0.0.1:5000/static/manifest.appcache offline-app:1

Application Cache Checking event offline-app:1

Application Cache Downloading event offline-app:1

Application Cache Progress event (0 of 2) http://127.0.0.1:5000/style.css offline-app:1

Application Cache Error event: Resource fetch failed (404) http://127.0.0.1:5000/style.css

The error is in the last line.

When the appcache fails even once, it stops the process completely and the offline cache doesn't work.

This is how my files are structured:

  • sandbox
    • offline-app
      • offline-app.py
      • static
        • manifest.appcache
        • script.js
        • style.css
      • templates
        • offline-app.html

This is the content of offline-app.py:

from flask import Flask, render_template
app = Flask(__name__)

@app.route('/offline-app')
def offline_app():
    return render_template('offline-app.html')

if __name__ == '__main__':
    app.run(host='0.0.0.0', debug=True)

This is what I have in offline-app.html:

<!DOCTYPE html>
<html manifest="{{ url_for('static', filename='manifest.appcache') }}">
<head>
    <title>Offline App Sandbox - main page</title>
</head>
<body>
<h1>Welcome to the main page for the Offline App Sandbox!</h1>
<p>Some placeholder text</p>
</body>
</html>

This is my manifest.appcache file:

CACHE MANIFEST
/style.css
/script.js

I've tried having the manifest file in all different ways I could think of:

CACHE MANIFEST
/static/style.css
/static/script.js

or

CACHE MANIFEST
/offline-app/static/style.css
/offline-app/static/script.js

None of these worked. The same error was returned every time.

I'm certain the issue here is how the server is serving up the files listed in the manifest. Those files are probably being looked up in the wrong place, I guess. I either should place them somewhere else or I need something different in the cache manifest, but I have no idea what. I couldn't find anything online about having HTML5 offline applications with Flask.

Is anyone able to help me out?

Southeastward answered 27/6, 2013 at 19:43 Comment(0)
S
7

I would have thought this one would work:

CACHE MANIFEST
/static/style.css
/static/script.js

But in any case, you should not hardcode the URLs for your static files. It's best to serve the manifest as a template (moved to the "templates" folder) so that you can use url_for to generate the path to the static files, something like this:

CACHE MANIFEST
{{ url_for('static', filename='style.css') }}
{{ url_for('static', filename='script.js') }}

Then in your HTML template you would have a reference to a route instead of a static file:

<html manifest="{{ url_for('manifest') }}">

And finally, you would add a new view function that returns the manifest:

from flask import make_response

@app.route('/manifest')
def manifest():
    res = make_response(render_template('manifest.appcache'), 200)
    res.headers["Content-Type"] = "text/cache-manifest"
    return res
Solarize answered 27/6, 2013 at 22:19 Comment(1)
Changing it to be served as a template solved it for me. Thank you! For anyone that will use this in the future, there were just two small things missing from Miguel's answer: you need to add an import to make_response in your file (my .py has now "from flask import Flask, render_template, make_response") and in the view function insert a line below where the "Content-Type" header is set that returns the response (as in "return res").Southeastward

© 2022 - 2024 — McMap. All rights reserved.