Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Trailing slash triggers 404 in Flask path rule

Tags:

python

flask

I want to redirect any path under /users to a static app. The following view should capture these paths and serve the appropriate file (it just prints the path for this example). This works for /users, /users/604511, and /users/604511/action. Why does the path /users/ cause a 404 error?

@bp.route('/users') @bp.route('/users/<path:path>') def serve_client_app(path=None):     return path 
like image 983
Jesvin Jose Avatar asked Oct 20 '15 15:10

Jesvin Jose


People also ask

How do you fix a trailing slash?

A 301 redirect is the best way to resolve duplicate content issues caused by trailing slashes. If you're just fixing one page, you'd redirect the duplicate copy to the version that matches your chosen URL structure. Most trailing slash issues however, affect many pages across a website.

Should routes have trailing slash?

Historically, a trailing slash marked a directory and a URL without a trailing slash at the end used to mean that the URL was a file. Today, however, trailing slashes are purely conventional, and Google does not care whether you use them; as long as you're consistent.

What is a trailing slash in URL?

Historically, it's common for URLs with a trailing slash to indicate a directory, and those without a trailing slash to denote a file: http://example.com/foo/ (with trailing slash, conventionally a directory) http://example.com/foo (without trailing slash, conventionally a file)

What is a trailing backslash?

A trailing slash is the forward slash placed at the end of a URL. The trailing slash is generally used to mark a directory, and if a URL is not terminated using a trailing slash, this generally points to a file. However, these are guidelines, and not requirements.


1 Answers

Your /users route is missing a trailing slash, which Werkzeug interprets as an explicit rule to not match a trailing slash. Either add the trailing slash, and Werkzeug will redirect if the url doesn't have it, or set strict_slashes=False on the route and Werkzeug will match the rule with or without the slash.

@app.route('/users/') @app.route('/users/<path:path>') def users(path=None):     return str(path)  c = app.test_client() print(c.get('/users'))  # 302 MOVED PERMANENTLY (to /users/) print(c.get('/users/'))  # 200 OK print(c.get('/users/test'))  # 200 OK 
@app.route('/users', strict_slashes=False) @app.route('/users/<path:path>') def users(path=None):     return str(path)  c = app.test_client() print(c.get('/users'))  # 200 OK print(c.get('/users/'))  # 200 OK print(c.get('/users/test'))  # 200 OK 

You can also set strict_slashes for all URLs.

app.url_map.strict_slashes = False 

However, you should avoid disabling strict slashes in most cases. The docs explain why:

This behavior allows relative URLs to continue working even if the trailing slash is omitted, consistent with how Apache and other servers work. Also, the URLs will stay unique, which helps search engines avoid indexing the same page twice.

like image 159
davidism Avatar answered Sep 25 '22 01:09

davidism