开发者

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, "+").

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜