-
-
Notifications
You must be signed in to change notification settings - Fork 5.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Routing should be agnostic to leading and trailing slashes #848
Comments
In my opinion,
|
This becomes a bigger problem when different frameworks and different servers choose to strip trailing slashes |
@jscheel Can you suggest an example of how this might play out? @bradleywright I definitely see your point for the leading slashes vis-a-vis absolute and relative paths. But what about the trailing slash? How do you see the two cases |
Web servers treat them differently unless the URL routing used in front (by Rails or Django, for example) forces an implicit 302 or 301 to "normalise" the URL. A Google themselves note this. |
@bradleywright From a server stand-point, you're absolutely right. But what about the user's perspective? If the user visits your site by typing in |
Having the same resource served at two different URLs ( So your point about the user is fine, but that's an implementation detail in whatever you're using to route requests on the application server - IMO Backbone shouldn't make assumptions about things like that, so I feel that the route you put in Backbone should be the canonical one, and not a mix of the two. |
Yep. I'm afraid that in terms of backbone routes, which can (but don't have to be) client-side only ... a trailing slash should indeed be significant. If your route looks like this:
Then we certainly shouldn't be making it the same as this:
... by default. For the record, you should never be using leading slashes with Backbone routes -- any trailing characters are your own business. |
I know this issue is closed, but I really have to ask, what is the problem with leading slashes? Gmail and Twitter both do this, and I personally think index.html/#/login is MUCH more attractive than index.html#/login. I realize this may just be a personal preference, but what's the reason for preventing this behavior, as I notice is being done in 0.9.0? |
I think it's actually forcing it to `````` index.html/#login
|
So, the way I see it, if we want to allow trailing slashes in our backbone app we have to add duplicate routes all over the place? If this issue is going to be closed as "won't fix" I think there should at least legit comment explaining how to solve this problem for those of us philistines who just want to allow trailing slashes in our awfully coded, bad practice ridden app. |
I've just stumbled across this issue and would like to provide a simple solution for cases where your api framework treats urls with and without trailing slashes as the same. This may be confusing for your user, because entering With apache modify your .htaccess to redirect the user to non-trailing-slash equivalent of the url:
|
In my router's initialization method I manually added a catchall route that removes trailing slashes if this is helpful to anyone. var re = new RegExp("(\/)+$", "g");
/*jshint regexp: false*/
this.route(/(.*)\/+$/, "trailFix", function (id)
// remove all trailing slashes if more than one
id = id.replace(re, '');
this.navigate(id, true);
}); |
+1 |
@vincentbriglia thanks for that snippet for removing the trailing slashes! I added a missing { right after the function on line 3. I've added it below. var re = new RegExp("(\/)+$", "g");
/*jshint regexp: false*/
this.route(/(.*)\/+$/, "trailFix", function (id) {
// remove all trailing slashes if more than one
id = id.replace(re, '');
this.navigate(id, true);
}); |
I do know this thread is fairly old and closed, but I have a solution and thought it may help anyone looking to accomplish this. If you re-write the Additionally, if you would like the route to also be case insensitive, this is also the place to do it by adding the _routeToRegExp: function (route) {
var namedParam = /:\w+/g;
var splatParam = /\*\w+/g;
var escapeRegExp = /[-[\]{}()+?.,\\^$|#\s]/g;
route = route.replace(escapeRegExp, '\\$&')
.replace(namedParam, '([^\/]+\/?)')
.replace(splatParam, '(.*?)');
return new RegExp('^' + route + '$');
/*
* Note: If you would like case insensitivity,
* add the "i" attribute to the return
* return new RegExp('^' + route + '$', 'i');
*/
} Note: This method is an exact copy for the one in the default backbone library, but I moved the variables into the function. |
@joshpangell Support for optional groups was added in #1509. You can now do the following: var Router = Backbone.Router.extend({
routes: {
'route(/)': 'route'
},
route: function() {...}
}); |
@braddunbar any idea when the next version of backbone will be released? it would be great to have this feature (as well as other features and fixes that have been done since 0.9.2 came out around 9 months ago). |
@mindscratch soon - see here - #1885 |
Yep, very soon. :) |
for what its worth... I appreciate SEO is usually ignored / not an issue with single page apps based on backbone, but if you allow urls both with and without trailing / it is detrimental to your sites SEO as each page is viewed as duplicated. As previously mentioned you are better off setting apache or similar to manage the invalid url and redirect to the valid one. |
Thanks @ptnplanet and @andrewtennison - I opted to change our framework so that no trailing slashes would ever be used. We're using WordPress, so I simply created a custom permalink in 'Settings > Permalinks' of /%postname% without a trailing slash, works great. |
@braddunbar i love you. (/) totally worked. I just put it in my _routeToRegExp thingy. |
Glad I could help! 😄 |
I am frustrated that backbone defined its own URI scheme that is not inline with the HTTP URI scheme. RFC 3986 (Updated, but not obsoleted by RFC 6874) Section 6.2.3 states, and gives an example, that an empty segment path is the same as a segment ending with "/". Specifically, this is addressed for the root of the URI. It is important to understand Section 6 to build context around applying this to URI segments. Section 5.4.1 can also be referenced for some examples. In fact, RFC 2616 (the HTTP RFC, updated by a few RFcs, but not obsoleted) specifically states how to compare URLs in Section 3.2.3.
Section 5.1.2 and Section 3.2.2 state the structure of a request URI and define what
It is erroneous for backbone to treat trailing slashes and non-present trailing slashes as nonequivalent. This issue should be reopened and reconsidered. |
Eh? I don't mean to be rude here — but that's an extremely strong appeal to authority without actually 1) looking at what servers do with trailing slashes on the web currently, and 2) carefully reading what those RFCs are saying. When they mean "an empty segment path", and "an empty abs_path", they're talking about a truly empty path ... i.e., the root of the server, which is all well and fine. Trailing slashes as part of a non-empty path are (perhaps wrongly) entirely semantic. Some servers will redirect you to the equivalent automatically, but many will not. Backbone needs to support use cases that prefer not to have:
... also be served when the user navigates to a broken URL like:
Now, let's look in the wild. Say at the W3C, for an example. This page (http://www.w3.org/standards/webdesign/htmlcss) is served without a trailing slash. Try visiting it with one, and see where you get: http://www.w3.org/standards/webdesign/htmlcss/ "own URI scheme that is not inline with the HTTP URI scheme" my arse. |
Would you care to enlighten me on the parts I'm not carefully reading? Further references:
And herein lies the issue. Neither RFC states whether a URI with a trailing slash is equivalent to one without. After a fairly thorough reading, I have interpreted both to mean they are equivalent; other's will disagree, as you have. Can you also clarify why that URL is broken?
.
I refute that I am making an appeal to authority. An appeal to authority roughly follows this idea:
When RFCs are accepted, they become the de facto specification for the concepts they describe. Even if you are claiming the RFC is the authority I am appealing to, appeals to authority are not necessarily fallacious, as you seem to be implying. It's the misuse of appeals to authority that are problematic. Now, referencing what the W3C does with that specification is a misuse of an appeal to authority, and is a fallacy.
Now, while we're on the subject of logical fallacies, consider also the "fallacy fallacy." If a fallacy is committed, it does not necessarily invalidate the argument. Your example, for example, props up your interpretation. While this is a fallacious appeal to authority, it is important for developers to consider what happens out there. To that end, I understand why backbone treats the URLs differently, whether or not I agree with it. Here are some examples that support my interpretation of the RFCs. These are all fallacious appeals to authority, but must be considered for practicalities sake.
There's no need for snark. This is an issue tracking forum, not a roast. With all this out of the way, understanding your point about needing to support both cases, perhaps some form of configuration option is a more workable solution than treating "/" as an optional part of the route definition? |
Sure, that sounds like a fine idea. Want to cook up a pull request? |
…ter so application authors can determine whether their applications treats URIs with a trailing slash as a different resource than URIs without a trailing slash. Defaults to true. This option causes Router to set the 'routeTrailingSlashPattern' variable, which is added to the overall URIs matching regex. jashkenas#848
Just out of curiosity: what's wrong with leading slashes? I've spent some time googling and found several statements against it e.g. here @jashkenas and in the official docs:
but not a word - why. |
Well, I think leading slashes are stripped from routes before any handling takes place. If nothing else, they're superfluous in Backbone routes. |
There's no technical reason if you're using hashchange -- they're just ugly, but were trendy for a brief period. Leading slashes make no sense if you're using pushstate. |
Got it. Thanks. |
(Apologies for the revival) #1885 says the update included:
But on Backbone 1.3.3 I'm continuing to see the issue of '.../foo' and '.../foo/' treated differently. Thanks. |
@raymondji use From the doc on
|
Currently, defining routes as
"/search"
is not equal to"search"
, which is also not equal to"search/"
or"/search/"
. Backbone should consider all of these routes as equal, so that all routing is agnostic to the leading and trailing slashes.The text was updated successfully, but these errors were encountered: