Are there any downsides to using double-slashes in URLs?
Asked Answered
K

2

15

I've written my own MVC framework in PHP, which uses urls in the format of:

/controller/method/param1/param2/param...

I've made it so that "default" methods can be ignored (by default index()), so this results in URLs like /controller//param1/param2/param.... For example, a URL of: /view//panel-glide/3 will call index('panel-glide', 3) in the view controller.

This works fine and dandy, but I'm concerned that search engines or some older browsers might freak out when they see the double slashes, as I don't think I've actually seem them ever be used before.

Is anyone aware of any issues I might come across by using this?

Kellam answered 29/6, 2012 at 4:46 Comment(6)
Just a side note: why not enforce a rigid structure of controller/method?param1=value1&param2=value2...? Seems much more RPC-like to me.Acidic
@LiorCohen Drupal for instance accepts a format like you suggest but rewrites the url to the OP's format. It's possible he just omitted that that is being done behind the scenes.Muscovado
My primary concern is flexibility rather than strict structural enforcements. And query string parameters are still accessible with my input class (e.g. $this->input->get('param')` would return value1). I want to allow URI segments to be parsed as method parameters (like in CodeIgniter) for ease of use and nicer urls (like /blog/post/hello-world-foo-bar-baz)Kellam
Search engine issue: Apache Solr's JSON parser cannot handle a double slash; their extension adding comments to JSON grammar is broken and the slashes will comment out the closing quote of a stringKodok
@Kodok I think you should post that as an answer.Muscovado
@pyrokinetiq Using double-slashes as you're doing is perfectly ok according to the multiple URL and URI standards. BUT, using two slashes where only was meant is a very common error, so there are a lot of applications that normalize multiple contiguous slashes in path to just one slash. This will cause errors for you too. For example, a lot of crawlers will fail to crawl your site correctly, since normalizing multiple slashes is a very common practice.Kyongkyoto
P
17

There is an existing answer on WebMasters that discusses the dangers of having two slashes. It discusses Apache a lot, but the ideas should be applicable generally.

In essence, I don't think it is recommended. /foo/bar and /foo//bar really should be two completely different paths. Each slash is significant, and attempts at circumventing that standardization are bound to come back to bite you.

As is mentioned in the answer, there's also a very real danger of relative paths failing. Some browsers will correctly figure that a relative path ../../fizz from /foo/bar//baz is /foo/bar/fizz, while others will treat the double slash as a single one, and opt for /foo/fizz.

Plus, I think it looks funny.

Profitsharing answered 29/6, 2012 at 4:56 Comment(8)
I agree. As a developer it looks funny. As a user it looks funny. Actually, if I bookmarked that url and the link was broken, I would expect removing the extra / to fix it. And tbh, a change in the code might make that happen.Muscovado
@nomaD Just rewrite the extra / out of there.Muscovado
In my case /foo/bar and /foo//bar ARE two completely different paths. /foo/bar will be loading the bar() method/action of the foo controller, /foo//bar will be loading index('bar') of the foo controller.Kellam
I agree. A user typing a URL like that is likely to feel confused.Savory
@nomaD: There's more to it than just aesthetics. See my edit. Is there a reason why you don't want to make the /foo/index an explicit URL?Profitsharing
Ah that's the sort of answer I was looking for, I wanted to know if there's any actual issues with my implementation rather than whether or now it would work (which it does) :). And /foo/index is an explicit URL, I just thought being able to exclude /index would be a lot nicer aesthetically, so you could load the default method (index()) of foo by simply going to /foo.Kellam
@nomaD: If your routing engine is clever enough, there's also the option of having /foo call the default index() method on the foo controller, and then for more complex URLs, like /foo/bar/baz, it would first try to find a bar() method and, only when that fails, it will try to call the index() method using bar and baz as arguments. Makes it a bit more complex, and there's probably a slight performance tradeoff, but might achieve what you're describing. Of course, there's also the danger of bar being both a method and an argument to index() at different times...Profitsharing
@nomaD: So, actually, you might not want to try that. :]Profitsharing
M
3

Apache treats multiple slashes as a single slash. This affects things such as RewriteRules, e.g. if you have a rule like this:

RewriteRule ^user/(.*)/([0-9]+)$ /user.php?id=$2 [QSA,L]

That will catch links such as user/nomaD/500 but it will not catch user//500 since it treats that as user/500

So in other words, I don't think your setup will work since it will treat param1 as method and shift all the parameters left, unless they are of a specific type. I guess this doesn't affect your specific case, but in a lot of situations, this would be a downside to using //.

Maxwellmaxy answered 29/6, 2012 at 4:58 Comment(5)
But he said it did work. I guess he could not be on apache and you both be right.Muscovado
My setup does work, I'm using a catch-all rewrite: RewriteRule ^(.*)$ index.php?$1 [L], then using PHP to parse the url and figure out what to be loadingKellam
Maybe he is breaking apart the REQUEST_URI to separate the parameters out thenMaxwellmaxy
A brilliant insight. Makes good sense though. PHP doesn't care what apache thinks about double slashes.Muscovado
Yep, I'm using PHP to explode the URL by '/', $segment[0] is the controller to load, segment[1] is the method/action (and if ($segment[1] == '') $segment[1] = 'index';, and all following segments are used as parameters for the method. So /blog//first-post would essentially run $framework->blog->index('first-post') and /blog/first-post would run $framework->blog->first-post() which wouldn't exactly work ;)Kellam

© 2022 - 2024 — McMap. All rights reserved.