Trailing slash: Difference between revisions
mNo edit summary |
mNo edit summary |
||
(One intermediate revision by the same user not shown) | |||
Line 32: | Line 32: | ||
Interpretation of the URL is up to the server, so these are two different requests | Interpretation of the URL is up to the server, so these are two different requests. | ||
The two ''could'' be made to display different content. | |||
Or not. | |||
In some cases that may be confusing {{comment|(and in the case of the root path, it's impossible because the path in the request - think {{inlinecode|GET / HTTP/1.0}} - can't be empty without it being a bad request{{verify}})}}. | In some cases that may be confusing {{comment|(and in the case of the root path, it's impossible because the path in the request - think {{inlinecode|GET / HTTP/1.0}} - can't be empty without it being a bad request{{verify}})}}. | ||
Line 40: | Line 42: | ||
The question isn't | The question isn't | ||
* figuring out what to send to the user {{comment|(that is usually well defined)}}, | |||
* or even whether crawlers will get confused {{comment|([https://developers.google.com/search/blog/2010/04/to-slash-or-not-to-slash they ''shouldn't'']. | |||
:: In theory reacting to both is duplicate content, but not in a way they care much about)}}. | :: In theory reacting to both is duplicate content, but not in a way they care much about)}}. | ||
The question is often whether there will ''ever'' be paths under that, because if so, that gets very messy immediately. | The question is often | ||
* whether there will ''ever'' be paths under that, because if so, that gets very messy immediately. | |||
Consider that if you 'mount' an app under a path, e.g. so that the browser requests | Consider that if you 'mount' an app under a path, e.g. so that | ||
the browser requests: | |||
/myapp/css | /myapp/css | ||
and | and internally that mounting logic implies you want that app to see only: | ||
/css | /css | ||
...CGI-variable-wise {{comment|(which only matters for frameworks that choose to adhere to these [[CGI,_FastCGI,_SCGI,_WSGI,_servlets_and_such#CGI_variables.2C_HTTP_variables.2C_and_similar|CGI variable]] conventions, but may do)}}, this means moving elements from PATH_INFO to SCRIPT_NAME (or at least remove the lead-in path fro PATH_INFO), so that | ...CGI-variable-wise {{comment|(which only matters for frameworks that choose to adhere to these [[CGI,_FastCGI,_SCGI,_WSGI,_servlets_and_such#CGI_variables.2C_HTTP_variables.2C_and_similar|CGI variable]] conventions, but may do)}}, this means moving elements from PATH_INFO to SCRIPT_NAME (or at least remove the lead-in path fro PATH_INFO), so that | ||
Line 62: | Line 68: | ||
If you ''do'' serve the app from that, then any relative paths the app gives back make no sense, because the UA will considers them relative to / and not to /myapp/ | If you ''do'' serve the app from that, then any relative paths the app gives back make no sense, because the UA will considers them relative to / and not to /myapp/ | ||
You | You '''cannot''' fix that in the app, because the thing that leads to the mistake was made external to it. | ||
A better solution would be o have {{inlinecode|/myapp}} redirect to {{inlinecode|/myapp/}} and have the app react only if that final slash is involved. | |||
And that basically implies that your mounting logic has to know when to do that. | And that basically implies that your mounting logic has to know when to do that. | ||
Line 69: | Line 76: | ||
...but | ...but practically, there various cases where you can get away with not doing that. | ||
* Say, if an app doesn't have any paths | * Say, if an app doesn't have any paths | ||
Latest revision as of 15:52, 21 March 2024
In filesystem paths
In HTTP
Consider:
http://example.com/path http://example.com/path/
Should these be considered the same?
The short answer is no.
Interpretation of the URL is up to the server, so these are two different requests.
The two could be made to display different content. Or not.
In some cases that may be confusing (and in the case of the root path, it's impossible because the path in the request - think GET / HTTP/1.0 - can't be empty without it being a bad request(verify)).
The question isn't
- figuring out what to send to the user (that is usually well defined),
- or even whether crawlers will get confused (they shouldn't.
- In theory reacting to both is duplicate content, but not in a way they care much about).
The question is often
- whether there will ever be paths under that, because if so, that gets very messy immediately.
Consider that if you 'mount' an app under a path, e.g. so that the browser requests:
/myapp/css
and internally that mounting logic implies you want that app to see only:
/css
...CGI-variable-wise (which only matters for frameworks that choose to adhere to these CGI variable conventions, but may do), this means moving elements from PATH_INFO to SCRIPT_NAME (or at least remove the lead-in path fro PATH_INFO), so that
- the code that tests PATH_INFO for what to serve does not see that lead-in path.
- http://$SERVER_NAME:$SERVER_PORT$SCRIPT_NAME$PATH_INFO still points to the current script
All fine, but it leaves the question of what to do with the request to the exact path of
/myapp
If you do serve the app from that, then any relative paths the app gives back make no sense, because the UA will considers them relative to / and not to /myapp/
You cannot fix that in the app, because the thing that leads to the mistake was made external to it.
A better solution would be o have /myapp redirect to /myapp/ and have the app react only if that final slash is involved.
And that basically implies that your mounting logic has to know when to do that.
...but practically, there various cases where you can get away with not doing that.
- Say, if an app doesn't have any paths
- when you can get away with guessing the best, or fix it dynamically
- one example is where URL paths are mapped to filesystem paths, where you can figure out what to do based on directory entry
- though even here, some servers will do external redirect to an URL with a /
- but note that this only works within an app - not so much at its root