【问题标题】:ActionView::Template::Error (incompatible character encodings: UTF-8 and ASCII-8BIT)ActionView::Template::Error(不兼容的字符编码:UTF-8 和 ASCII-8BIT)
【发布时间】:2011-07-10 03:56:40
【问题描述】:

我正在使用 Ruby 1.9.2、Rails 3.0.4/3.0.5 和 Phusion Passenger 3.0.3/3.0.4。我的模板是用 HAML 编写的,我使用的是 MySQL2 gem。我有一个控制器操作,当传递一个具有特殊字符(如变音符号)的参数时,会出现以下错误:

ActionView::Template::Error (incompatible character encodings: UTF-8 and ASCII-8BIT)

错误指向我的 HAML 模板的第一行,上面有以下代码:

<!DOCTYPE html>

我的理解是,这是因为我有一个 UTF-8 字符串与一个 ASCII-8BIT 字符串连接,但我终生无法弄清楚那个 ASCII-8BIT 字符串是什么。我检查了操作中的参数是否使用 UTF-8 进行编码,并且我在 HAML 模板和 ruby​​ 文件的顶部添加了一个 encoding: UTF-8 声明,但我仍然收到此错误。我的 application.rb 文件中也有一个 config.encoding = "UTF-8" 声明,以下都导致 UTF-8:

ENV['LANG']
__ENCODING__
Encoding.default_internal
Encoding.default_external

问题来了:我无法在我的 Mac-OSX 上本地重现此结果,无论是在开发还是生产中使用独立的乘客或杂种。我只能在 linux 上运行 nginx+passenger 的生产服务器上重现它。我已经在生产服务器的控制台中验证了后者提到的命令也都导致 UTF-8。

您是否遇到过同样的错误,您是如何解决的?

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-3 passenger ruby-1.9.2


    【解决方案1】:

    Mysql 可能是麻烦 ascii 的来源。尝试将以下内容放入初始化程序中以至少消除这种可能性:

    require 'mysql'
    
    class Mysql::Result
      def encode(value, encoding = "utf-8")
        String === value ? value.force_encoding(encoding) : value
      end
    
      def each_utf8(&block)
        each_orig do |row|
          yield row.map {|col| encode(col) }
        end
      end
      alias each_orig each
      alias each each_utf8
    
      def each_hash_utf8(&block)
        each_hash_orig do |row|
          row.each {|k, v| row[k] = encode(v) }
          yield(row)
        end
      end
      alias each_hash_orig each_hash
      alias each_hash each_hash_utf8
    end
    



    编辑

    这可能不适用于 mysql2 gem。但是适用于 mysql。

    【讨论】:

    • 我知道这个解决方案,但它是针对 mysql gem 而不是 mysql2 gem。 mysql2没有这个问题。此外,无论我是否查询数据库,我都会得到相同的结果。
    【解决方案2】:

    在进行一些调试后,我发现使用 ActionDispatch::Request 对象时会出现问题,该对象恰好具有全部以 ASCII-8BIT 编码的字符串,无论我的应用程序是否以 UTF-8 编码。我不知道为什么只有在 Linux 上使用生产服务器时才会发生这种情况,但我认为这是 Ruby 或 Rails 中的一些怪癖,因为我无法在本地重现此错误。错误是因为这样的一行而发生的:

    @current_path = request.env['PATH_INFO']
    

    当在 HAML 模板中打印此实例变量时,它会导致错误,因为字符串是用 ASCII-8BIT 而不是 UTF-8 编码的。为了解决这个问题,我做了以下事情:

    @current_path = request.env['PATH_INFO'].dup.force_encoding(Encoding::UTF_8)
    

    这迫使@current_path 使用强制转换为正确 UTF-8 编码的重复字符串。其他与请求相关的数据(例如 request.headers)也会发生此错误。

    【讨论】:

    • 有同样的错误,我想知道为什么在生产 Nginx/passenger 上会发生这种情况。它的 LC_All 设置正确。但是请求 .env 是 ASCII。在本地服务器上,它的 utf-8k
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-04-14
    • 1970-01-01
    • 2016-02-12
    • 2011-07-14
    • 1970-01-01
    • 2011-10-17
    • 2011-05-26
    相关资源
    最近更新 更多