URL Encoding in JS for meaningful URLs and Rails Page Caching
I'm running a Rails Application which gets a lot of traffic at the moment so I started using Page Caching to increase the performance. So far everything works like a charm. But when I tried to also cache search results I run into a strange problem.
My Approach:
- Use meaningful URLs for searching and pagination (/search?query=term&page=3 becomes /search/term/3)
- Use Javascript to submit the form - if JS is disabled it falls back to the old form (which also works with my routes, but without caching)
My Code:
// Javascript
function set_search_action() {
window.location = '/search/' + escape(document.getElementById('query').value);
return false;
}
// HTML
<form action="/search" id="search_form" method="get" onSubmit="return set_search_action();">
<input id="query" name="query" title="Search" type="text" />
<input class="submit" name="commit" type="submit" value="Search" />
</form>
The Problem
Everything works for single words like "term". But when I search for "term1 term2" the form is submitted to /search/term1 term2/ or /search/term1 term2/1 . It should be submitted to /search/term1+term2 That's what the JS escape function should do I think.
So far it works also with spaces in development mode. But I guess it wi开发者_Python百科ll become a problem in production mode with caching enabled (URLs shouldn't contain any whitespaces).
Any ideas on what I did wrong? Thanks!
It should be submitted to /search/term1+term2
Nope. Plus symbols only represent spaces in application/x-www-form-urlencoded
content, such as when the query-string part of the URL is used to submit a form. In the path-part of a URL, +
simply means plus; space should be encoded to %20
instead.
That's what the JS escape function should do I think.
Yes it does, and that's the problem. escape
encodes spaces to +
, which is only suitable for form submissions; used in a path, you will get an unexpected and unwanted plus sign. It also mangles non-ASCII characters into an arbitrary format specific to the escape
function that no URL-decoder will be able to read.
As Tomalak said, escape()
/unescape()
is almost always the wrong thing, and in general should not be used. encodeURIComponent()
is usually what you really want, and will produce %20
for spaces, which is safe as it is equally valid in the path part or the query string.
Never use escape()
! It's broken and highly dis-recommended for what you do. Use encodeURIComponent()
instead.
To have +
instead of %20
, append a .replace(/%20/g, "+")
.
精彩评论