ActionView :: Template :: Error(不兼容的字符编码:UTF-8和ASCII-8BIT)

Pan*_*kos 15 ruby ruby-on-rails passenger ruby-on-rails-3 ruby-1.9.2

我使用的是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)
Run Code Online (Sandbox Code Playgroud)

该错误指向我的HAML模板的第一行,其中包含以下代码:

<!DOCTYPE html>
Run Code Online (Sandbox Code Playgroud)

我的理解是,这是因为我有一个UTF-8字符串与ASCII-8BIT字符串连接,但我不能在我的生活中找出ASCII-8BIT字符串是什么.我已经检查过动作中的参数是使用UTF-8编码的,我已经添加了一个编码:UTF-8声明到HAML模板的顶部和ruby文件,我仍然得到这个错误.我的application.rb文件中也有一个config.encoding = "UTF-8"声明,以下所有结果都是UTF-8:

ENV['LANG']
__ENCODING__
Encoding.default_internal
Encoding.default_external
Run Code Online (Sandbox Code Playgroud)

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

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

Pan*_*kos 12

在做了一些调试之后,我发现当使用ActionDispatch :: Request对象时会发生问题,该对象恰好具有以ASCII-8BIT编码的字符串,无论我的应用程序是否以UTF-8编码.我不知道为什么这只会在Linux上使用生产服务器时发生,但我会假设它在Ruby或Rails中有些怪癖,因为我无法在本地重现此错误.特别是因为这样的行发生了错误:

@current_path = request.env['PATH_INFO']
Run Code Online (Sandbox Code Playgroud)

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

@current_path = request.env['PATH_INFO'].dup.force_encoding(Encoding::UTF_8)
Run Code Online (Sandbox Code Playgroud)

强制@current_path使用强制进入正确的UTF-8编码的重复字符串.与其他请求相关的数据也会发生此错误request.headers.


art*_*ave 9

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
Run Code Online (Sandbox Code Playgroud)



编辑

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