10

I writing an app in Angular + Flask hosted on heroku. I've been looking to use html5mode to use myapp.co/register for oauth. The problem with html5mode is that server needs to rewrite url if someone refreshes the page or clicks the link that is not root. I tried to use this snippet to catch them all, but it doesn't work.

@app.route("/", defaults={"path": ""})
@app.route("/<path:path>")
def index(path):
  print path
  return make_response(open(app.static_folder + "index.html").read())

output 404

 * Restarting with reloader
127.0.0.1 - - [23/Jan/2014 13:41:48] "GET /ass HTTP/1.1" 404 -

App got root that servers index.html and /api/v1/ that is RESTful api

Lukasz Madon
  • 14,664
  • 14
  • 64
  • 108

2 Answers2

23

You need to use something more than you have:

@app.route("/", defaults={"path": ""})
@app.route("/<string:path>") <--- this is missing
@app.route("/<path:path>")
def index(path):
  print path
  return make_response(open(app.static_folder + "index.html").read())

So:

@app.route("/<string:path>")

is missing. It catches string variables (not path), so in your case just ass from your example, when you try to hit http://localhost:5000/ass.

turkus
  • 4,637
  • 2
  • 24
  • 28
  • 1
    I am wondering why is this missing in the official documentation. See: [Flask | Single-Page Applications](https://flask.palletsprojects.com/en/1.1.x/patterns/singlepageapplications/) – Koray Kural Oct 21 '20 at 09:39
11

Your code will catch all urls if you do not have any more routes with more highest priority. But look like it should return 500 error (because I hope you do not have <app_path>/staticindex.html and use unsafe method to send file).

So if you have another rules you must look at rule priority (see https://stackoverflow.com/a/17146563/880326).

If you have error with this route better use:

@app.route("/", defaults={"path": ""})
@app.route("/<path:path>")
def index(path)
    return send_from_directory(app.static_folder, "index.html")
Community
  • 1
  • 1
tbicr
  • 24,790
  • 12
  • 81
  • 106
  • Thanks. By unsafe you mean that url is mapped to file path? whats the benefit of send_from_directory? – Lukasz Madon Jan 23 '14 at 17:27
  • Yes, somebody can try use send `../` or `~/` to path (probably it will not work with URL, but probably you can get it with any another way). `send_from_directory` (see http://flask.pocoo.org/docs/api/#flask.send_from_directory) is enough clever to avoid relative paths for directory with `safe_join` and have many options with `send_file`. For example flask `static` route used `send_from_directory`. It good for development, but for production better process this files with nginx or replace it with CDN URLs if you wish. – tbicr Jan 23 '14 at 21:45
  • For anyone using Flask with AngularJS, if you wish for your app to display current route on angular rather than spit out a 404 whenever you refresh the page, use @app.route("/") and set path parameter to None. – OzzyTheGiant Feb 28 '17 at 20:58
  • i had to remove the "static_url_path" from the flask initialization in order to make this work – Ben Yitzhaki Jan 08 '19 at 08:48