Проблема с кодировкой в Sprockets 3 при работе с HTML файлами

от автора

Я не так давно обновил один из проектов до Rails 4.2 и заметил интересный эффект: кодировка обработанных html файлов в ассетах меняется на ISO-8859-1.

Данная проблема актуальна для Sprockets 3.0.0 и 3.0.1.

Проблема нашлась в EncodingUtils#detect_html:

#... module Sprockets   # Internal: HTTP transport encoding and charset detecting related functions.   # Mixed into Environment.   module EncodingUtils     extend self       #...       # Public: Detect charset from HTML document. Defaults to ISO-8859-1.     #     # str - String.     #     # Returns a encoded String.     def detect_html(str)       str = detect_unicode_bom(str)         # Attempt Charlock detection       if str.encoding == Encoding::BINARY         charlock_detect(str)       end         # Fallback to ISO-8859-1       if str.encoding == Encoding::BINARY         str.force_encoding(Encoding::ISO_8859_1)       end         str     end     CHARSET_DETECT[:html] = method(:detect_html)   end end 

При загрузке файла Sprockets пытается определить стандарт юникода, почистить строку от BOM и вернуть в нужной кодировке. В случае с html, если не удалось определить кодировку на этом этапе, то пытаемся дать это сделать charlock_holmes (если он установлен), иначе принудительно конвертируем в ISO-8859-1.

Проблема в том, что BOM не является обязательным для UTF-8 и поэтому практически все редакторы сохраняют файлы в UTF-8 без BOM. А это значит, что метод `detect_unicode_bom` по большому счету является бесполезным и html файлы в ассетах всегда будут преобразованы в ISO-8859-1.

Решить проблему можно следующими способами:

1. Переопределить Mime Type для text/html в инициализаторе:

Rails.application.assets.register_mime_type('text/html', extensions: '.html', charset: :default) 

2. Установить charlock_holmes.

3. Обновиться до версии 3.0.2, где поведение по умолчанию изменено с ISO-8859-1 на Encoding.default_external (pull request)

ссылка на оригинал статьи http://habrahabr.ru/post/256523/


Комментарии

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *