2010-05-28 2 views
2

Я запускаю приложение Rails, которое получает большой трафик на данный момент, поэтому я начал использовать кэширование страниц для повышения производительности. Пока все работает как шарм. Но когда я попытался также кэшировать результаты поиска, у меня возникла странная проблема.URL-кодирование в JS для значимых URL-адресов и Rails-страниц Кэширование страниц

Мой подход:

  • Используйте осмысленные URL-адреса для поиска и разбиение на страницы (/ поиск запроса = термин & страница = 3 становится/поиск/термин/3?)
  • Используйте Javascript для отправки формы - если отключен JS он возвращается к старой форме (которая также работает с моими маршрутами, но без кэширования)

Мой код:

// 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> 

Проблема

Все работает для одного слова, как "термин". Но когда я ищу «term1 term2», форма представляется в /search/term1 term2/ или /search/term1 term2/1. Он должен быть отправлен в /search/term1 + term2 Вот что должно сделать функция JS escape.

Пока он работает также с пространством в режиме разработки. Но я думаю, что это станет проблемой в режиме производства с включенным кешированием (URL-адреса не должны содержать пробелов).

Любые идеи о том, что я сделал не так? Благодаря!

ответ

6

Он должен быть представлен/поиск/TERM1 + term2

Неа. Плюс символы представляют только пробелы в содержимом application/x-www-form-urlencoded, например, когда часть строки запроса URL-адреса используется для отправки формы. В пути к URL-адресу + просто означает plus; пространство должно быть закодировано вместо %20.

Это то, что я должен сделать с функцией JS.

Да, это так, и в этом проблема. escape кодирует пробелы до +, что подходит только для представлений форм; используемый в пути, вы получите неожиданный и нежелательный знак плюса. Он также управляет символами, отличными от ASCII, в произвольном формате, специфичном для функции escape, которую URL-декодер не сможет прочитать.

Как сказал Томалак, escape()/unescape() почти всегда ошибочно, и в целом его не следует использовать.encodeURIComponent() обычно то, что вы действительно хотите, и будет производить %20 для пробелов, что является безопасным, так как оно равнозначно в части пути или строке запроса.

+0

+1 для подробного объяснения того, где и когда действует '% 20'. – Tomalak

3

Никогда не использовать escape()! Он сломан и очень не рекомендуется для того, что вы делаете. Вместо этого используйте encodeURIComponent().

Чтобы иметь + вместо %20, добавьте .replace(/%20/g, "+").

+0

Как указывает @bobince, символ '+' действителен только в строке запроса. И даже там он может быть заменен '% 20' без проблем. – Tomalak