-2

I'm studying flask, and got problems.

When I wrote code like this:

@app.route("/reference")
def reference():
    return render_template("reference.html", css="reference", records=records)

The page http://127.0.0.1:5000/reference was working.

Then I found 'trailing slash' in flask document.

I wanted to apply it, so I edited code like this:

@app.route("/reference/")
def reference():
    return render_template("reference.html", css="reference", records=records)

It was working too ! http://127.0.0.1:5000/reference/

But some problems were coming.

The browser couldn't read my css file (in html link.. href=blabla) with a changed log in python terminal.

GET /static/css/style.css HTTP/1.1 << before changing
GET /reference/static/css/style.css HTTP/1.1 << after changing

I redirected css file path,

href="static/css/style.css"
to
href="../static/css/style.css"

And It works.

I wanted to understand how 'trailing slash' do.

So I reset my code to first code.

Then 404 not found error raised and I got a not changed log.

"GET /reference HTTP/1.1" << log for first code
"GET /reference/ HTTP/1.1" << log for second code
"GET /reference/ HTTP/1.1" << log for reset code (== first code)

I got a question. What is happend?

I don't understand why it doesn't run like before.

I read https://flask.palletsprojects.com/en/2.0.x/quickstart/#unique-urls-redirection-behavior

But I still don't understand what is going on.

Why the GET path changed.. why the GET path doesn't changed.. why..

My mind is broken and I can't sleep.. please help me..

이상민
  • 1
  • 1
  • Did you use the template tag for your CSS URL as described in https://flask.palletsprojects.com/en/2.0.x/tutorial/static/ ? – Klaus D. Sep 12 '21 at 21:12
  • Yes. In my layout.html, is there. The reason I talked about css in the text is because I wanted to talk about one Symptom. because layout.html got another css link. I want to use href="{{ url_for('static', filename='css/style.css') }}" to another css, but css arg came from server and I try href="{{ url_for('static', filename='{{css}}/style.css') }}", it's not working. so I have to change my CSS URL like text. – 이상민 Sep 13 '21 at 02:34
  • Actually I want to know why app.route("/reference) works in only first time, not now. – 이상민 Sep 13 '21 at 02:36
  • https://github.com/Do-code-ing/Nomad_Job_Search/blob/master/templates/layout.html – 이상민 Sep 13 '21 at 02:40

1 Answers1

0

On top of what the unique-urls-redirection-behavior document says, when you use tags like <img src='some_url'> or <link href='some_url'> the behaviour may be different, as these URLs are loaded by the browser.

So with a route decorator like @app.route("/reference") which loads in the browser as example.com/reference a link tag with href="subpath/file.css" causes the browser to load that resource from example.com/subpath/file.css

On the other hand, with a route decorator like @app.route("/reference/") (with the trailing slash) which loads in the browser as example.com/reference/ (again, with the trailing slash) a link tag with href="subpath/file.css" causes the browser to load that resource from example.com/reference/subpath/file.css

This could explain the behaviour you are seeing.


To put this another way, consider this test app:

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

@app.route('/a')
def a(): return render_template('index.html')

@app.route('/b/') # Note trailing slash
def b(): return render_template('index.html')

Paired with the following template at templates/index.html:

<html>
<head>
    <link rel='stylesheet'  href='subpath/file.css' />
</head>

Then make some hits and observe the asset requests in the console (they will give 404 errors because I haven't actually created the CSS files, this is just to show what the browser requests):

Load URL: http://localhost:5000/a:

"GET /a HTTP/1.1" 200 -
"GET /subpath/file.css HTTP/1.1" 404 -

Load URL: http://localhost:5000/b/:

"GET /b/ HTTP/1.1" 200 -
"GET /b/subpath/file.css HTTP/1.1" 404 -

Of course the correct way to include these assets is to use the url_for function.

So if I update the template to instead contain:

  <link rel='stylesheet'  href='{{ url_for("static", filename="file.css") }}' />

Then make the same request:

Load URL: http://localhost:5000/a:

"GET /a HTTP/1.1" 200 -
"GET /static/file.css HTTP/1.1" 404 -

Load URL: http://localhost:5000/b/:

"GET /b/ HTTP/1.1" 200 -
"GET /static/file.css HTTP/1.1" 404 -

As you can see here, the correct path for static assets will always be rendered, regardless of whether the endpoint has a trailing slash or not.

v25
  • 7,096
  • 2
  • 20
  • 36
  • thanks for your answer with url_for behavior. then could you tell your idea to me why app.route("/a") doesn't work when I edited it app.route("/a/") and restore it? Is it a bug? my real question is it. – 이상민 Sep 13 '21 at 17:36