Кодировка URL в JS для значимых URL и кэширования страниц Rails - PullRequest
2 голосов
/ 28 мая 2010

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

Мой подход:

  • Используйте значимые URL для поиска и нумерации страниц (/ search? Query = term & page = 3 становится / search / term / 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 Это то, что должна делать функция escape JS.

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

Есть идеи, что я сделал не так? Спасибо!

Ответы [ 2 ]

6 голосов
/ 28 мая 2010

Должен быть представлен в / search / term1 + term2

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

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

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

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

3 голосов
/ 28 мая 2010

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

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

...