Проблема с кодировкой JSON в Ruby 1.9 и HTTParty

Я создал WebAPI, который возвращает JSON.

Исходные данные следующие (в кодировке UTF-8):

@text="Rosenborg har ikke h\xC3\xB8rt hva Steffen"

Затем с .to_json на моем объекте вот что отправляется API (я думаю, что это кодировка ISO-8859-1):

"text":"Rosenborg har ikke h\ufffd\ufffdrt hva Steffen"

Я использую HTTParty на стороне клиента, и вот что я наконец получаю:

"text":"Rosenborg har ikke h��rt hva"

И WebAPI, и клиентское приложение используют Ruby 1.9.2 и Rails 3.

Я немного запутался в этой проблеме с кодировкой... Я попытался добавить заголовок кодировки utf8 в свои файлы ruby, но это ничего не изменило. Я предполагаю, что мне где-то не хватает части кодирования/декодирования... у кого-нибудь есть идеи?

Спасибо большое !!! Винсент


person Vincent Peres    schedule 10.11.2010    source источник


Ответы (2)


В Ruby 1.9 кодирование теперь явное. Однако Rails может быть настроен или не настроен для отправки ответов в той кодировке, которую вы ожидаете. Вам нужно будет установить параметр глобальной конфигурации:

Encoding.default_external = "utf-8".

Я считаю, что кодировка, которую Ruby указывает по умолчанию для сериализации, является платформой по умолчанию. В Америке на Windows это будет CodePage-1251. В других странах будет альтернативная кодировка.

Изменить: также см. этот URL-адрес, если json выполняется для MySQL: https://rails.lighthouseapp.com/projects/8994/tickets/5210-encoding-problem-in-json-format-response

Изменить 2: ядро ​​Rails и его набор библиотек (ActiveRecord и др.) будут учитывать настройку конфигурации Encoding.default_external, которая кодирует все отправляемые значения. К сожалению, поскольку кодирование является относительно новой концепцией для Ruby, не каждая сторонняя библиотека была адаптирована для правильного кодирования. Те, которые имеют, могут потребовать дополнительных настроек конфигурации для этих библиотек. Это включает MySQL и библиотеку RSolr, которую вы использовали.

Во всех версиях Ruby до серии 1.9 строка была просто массивом байтов. Когда вы так долго думаете об этом, вам трудно усвоить концепцию множественных кодировок строк. Еще больше сбивает с толку то, что в отличие от Java, C# и других языков, использующих ту или иную форму UTF в качестве родного формата строки, Ruby позволяет кодировать каждую строку по-разному. Оглядываясь назад, это может быть ошибкой, но, по крайней мере, сейчас они уважают кодирование.

Метод Encoding.force_encoding предназначен для обработки последовательности байтов с помощью этой новой кодировки, но не изменяет никаких базовых данных. Таким образом, возможно наличие недопустимых последовательностей байтов. Существует еще один метод, называемый .encode(), который преобразует байты из одной кодировки в другую и гарантирует корректную последовательность байтов. Для получения дополнительной информации прочитайте это:

http://blog.grayproductions.net/articles/ruby_19s_string

person Berin Loritsch    schedule 10.11.2010
comment
Как мне изменить кодировку для сериализации? - person Oscar Kilhed; 12.11.2010
comment
Проверьте мою вторую правку. В нем гораздо больше информации о новых функциях кодирования Ruby 1.9 и вещах, о которых вам нужно помнить. - person Berin Loritsch; 12.11.2010
comment
У меня такая проблема, но с sqlite3. Работает очень хорошо, когда я визуализирую через представления, но с визуализацией: json я получаю именно эту проблему. - person Oscar Kilhed; 12.11.2010
comment
Вероятно, это означает, что данные, которые вы извлекаете из своей базы данных, не закодированы должным образом, вы должны проверить их с помощью метода my_string.encoding - person Vincent Peres; 12.11.2010

Ну наконец-то я понял в чем проблема...

Я использую RSolr для получения своих данных из Solr, и по умолчанию для всех результатов используется, к сожалению, кодировка «US-ASCII», как указано здесь (и проверено мной): http://groups.google.com/group/rsolr/browse_thread/thread/2d4890fa7737e7ef#

Итак, вам нужно принудительно кодировать следующим образом:

my_string.force_encoding(Encoding::UTF_8)

Возможно, есть хороший вариант кодирования для RSolr!

person Vincent Peres    schedule 11.11.2010