Отключите специальные символы правильно из URL в Rails 3.0.3 - PullRequest
7 голосов
/ 17 января 2012

Я использую Rails 3.0.3 с REE (Ruby 1.8.7) и гемом 'mysql2', '0.2.6'

В моем проекте есть функция поиска, которая позволяет людям использовать метод GET, используя URL-адрес или формы, а затем генерировать URL-адрес.

Пример:

Я хочу найти:

город происхождения: " Орхус, Дания " и город назначения: " Асунсьон, Парагвай "

они оба имеют специальный символ: " Å " и " - ", поэтому URL-адрес будет сгенерирован следующим образом, когда кто-то нажмет кнопку поиска.

?&origin=%C5rhus%2C%20Denmark&destination=Asunci%F3n%2C%20Paraguay

Проблема:

Когда я ищу этот город, он не покидает меня, как я хочу (я пытался использовать как CGI, URI, даже некоторые драгоценные камни)

Когда я вижу в консоли, ActiveRecord получил запрос, подобный этому:

Parameters: {"destination"=>"Asunci�n, Paraguay", "origin"=>"�rhus, Denmark", "sort"=>"newest"}
City Load (0.1ms)  SELECT `cities`.* FROM `cities` WHERE (`cities`.`name` = '�rhus') ORDER BY cities.name ASC
City Load (6.8ms)  SELECT `cities`.* FROM `cities` WHERE (`cities`.`name` = 'Asunci�n, Paraguay') ORDER BY cities.name ASC

Вывод: города не найдены : (

Но я нашел интересную вещь:

  • Когда я сделал ошибку в файле, связанном с этой функцией, вывод будет таким:

    Запрос

    Parameters:
    {"destination"=>"Asunción,
    Paraguay",
    "origin"=>"Århus,
    Denmark",
    "sort"=>"newest"}
    

это действительный!

Вопрос:

Ребята, у вас есть идея, как это решить? Заранее спасибо:)

1 Ответ

12 голосов
/ 17 января 2012

Вы правы, похоже, у вас где-то есть проблема с кодировкой. Символ 0xC5 - это «Å» в ISO-8859-1 (AKA Latin-1) , в UTF-8 это будет %C3%85 в URL.

Я подозреваю, что вы используете JavaScript на стороне клиента и ваш JavaScript использует функцию old escape для построения URL, escape имеет некоторые проблемы с не-ASCII символами. Если это так, то вам следует обновить JavaScript, чтобы использовать вместо него encodeURIComponent. Посмотрите на эту маленькую демонстрацию, и вы поймете, о чем я говорю:

http://jsfiddle.net/ambiguous/U5A3k/

Если вы не можете изменить скрипт на стороне клиента, вы можете сделать это сложным способом в Ruby, используя force_encoding и encoding:

>> s = CGI.unescape('%C5rhus%2C%20Denmark')
=> "\xC5rhus, Denmark"
>> s.encoding
=> #<Encoding:UTF-8>
>> s.force_encoding('iso-8859-1')
=> "\xC5rhus, Denmark"
>> s.encoding
=> #<Encoding:ISO-8859-1>
>> s.encode!('utf-8')
=> "Århus, Denmark"
>> s.encoding
=> #<Encoding:UTF-8>

Вы должны получить что-то вроде "\xC5rhus, Denmark" из params, и вы можете разобрать это с помощью:

s = params[:whatever].force_encoding('iso-8859-1').encode('utf-8')

Работа с этим на стороне сервера была бы последним средством, хотя, если ваш код на стороне клиента отправляет обратно неправильно закодированные данные, у вас останется куча догадок на сервере, чтобы выяснить, какая кодировка была на самом деле используется, чтобы получить его в URL.

...