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

发布于 2024-10-20 12:25:49 字数 859 浏览 6 评论 0原文

我正在使用 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​​ 文件的顶部添加了一个编码: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 生成。

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

I am using Ruby 1.9.2, Rails 3.0.4/3.0.5 and Phusion Passenger 3.0.3/3.0.4. My templates are written in HAML and I am using the MySQL2 gem. I have a controller action that when passed a parameter that has a special character, like an umlaut, gives me the following error:

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

The error points to the first line of my HAML template, which has the following code on it:

<!DOCTYPE html>

My understanding is that this is caused because I have a UTF-8 string that is being concatenated with an ASCII-8BIT string, but I can't for the life of me figure out what that ASCII-8BIT string is. I have checked that the params in the action are encoded using UTF-8 and I have added an encoding: UTF-8 declaration to the top of the HAML template and the ruby files and I still get this error. My application.rb file has a config.encoding = "UTF-8" declaration in it as well and the following all result in UTF-8:

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

Here's the kicker: I cannot reproduce this result locally on my Mac-OSX using standalone passenger or mongrel in either development or production. I can only reproduce it on a production server running nginx+passenger on linux. I have verified in the production server's console that the latter mentioned commands all result in UTF-8 as well.

Have you experienced this same error and how did you solve it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

不离久伴 2024-10-27 12:25:49

经过一些调试后,我发现使用 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)也可能会发生此错误。

After doing some debugging I found out the issue occurs when using the ActionDispatch::Request object which happens to have strings that are all coded in ASCII-8BIT, regardless of whether my app is coded in UTF-8 or not. I do not know why this only happens when using a production server on Linux, but I'm going to assume it's some quirk in Ruby or Rails since I was unable to reproduce this error locally. The error occurred specifically because of a line like this:

@current_path = request.env['PATH_INFO']

When this instance variable was printed in the HAML template it caused an error because the string was encoded in ASCII-8BIT instead of UTF-8. To solve this I did the following:

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

Which forced @current_path to use a duplicated string that was forced into the proper UTF-8 encoding. This error can also occur with other request related data like request.headers.

秋凉 2024-10-27 12:25:49

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 could be the source of troublesome ascii. Try putting the following in initializer to at least eliminate this possibility:

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

edit

This may not be applicable to mysql2 gem. Works for mysql however.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文