【问题标题】:Sinatra / Rack fails with non-ascii characters in urlSinatra / Rack 因 url 中的非 ascii 字符而失败
【发布时间】:2010-03-20 23:06:00
【问题描述】:

我在 /find/Wrocław 收到 Encoding::UndefinedConversionError "\xC5" 从 ASCII-8BIT 到 UTF-8

由于某种神秘的原因,sinatra 将字符串作为 ASCII 而不是 UTF-8 传递。

我发现了某种丑陋的解决方法...我不知道为什么 Rack 假定编码是 ASCII-8BIT ...无论如何,一种方法是使用 string.force_encoding("UTF-8").. . 但是为所有参数这样做很乏味

【问题讨论】:

  • 请问您在哪里添加了 string.force_encoding("UTF-8") 行?

标签: ruby sinatra rack


【解决方案1】:

我在路由到“/protégés/:id”时遇到了一些类似的问题。我posted 到 Rack 邮件列表,但反应不是很好。

我想出的解决方案并不完美,但它适用于大多数情况。首先,创建一个取消编码 UTF-8 的中间件:

# in lib/fix_unicode_urls_middleware.rb:
require 'cgi'
class FixUnicodeUrlsMiddleware
  ENVIRONMENT_VARIABLES_TO_FIX = [
    'PATH_INFO', 'REQUEST_PATH', 'REQUEST_URI'
  ]

  def initialize(app)
    @app = app
  end

  def call(env)
    ENVIRONMENT_VARIABLES_TO_FIX.each do |var|
      env[var] = CGI.unescape(env[var]) if env[var] =~ /%[A-Za-z0-9]/
    end
    @app.call(env)
  end
end 

然后在 config/environment.rb (Rails 2.3) 或 config/application.rb (Rails 3) 中使用该中间件。

您还必须确保设置了正确的编码 HTTP 标头:

Content-type: text/html; charset=utf-8

您可以在 Rails、Rack 或 Web 服务器中进行设置,具体取决于您在网站上使用了多少不同的编码。

【讨论】:

    【解决方案2】:

    AFAIK 你不应该在 URL 中有原始的 UTF-8 字符,但必须对它们进行 % 编码 ,不这样做可能会导致各种符合标准的代理的问题。看起来这不是机架问题,而是应用程序发出无效 URL 的问题。 HTTP 标头中的字符集和编码信息适用于内容而不是标头本身。

    引用RFC 3986

    当一个新的 URI 方案定义了一个表示由通用字符集 [UCS] 中的字符组成的文本数据的组件时,数据应首先根据 UTF-8 字符编码 [STD63] 编码为八位字节;那么只有那些与未保留集中的字符不对应的八位字节应该进行百分比编码。例如,字符 A 将表示为“A”,字符 LATIN CAPITAL LETTER A WITH GRAVE 将表示为“%C3%80”,字符 KATAKANA LETTER A 将表示为“%E3%82%A2 ”。

    【讨论】:

      猜你喜欢
      • 2019-04-06
      • 2018-04-08
      • 2012-01-02
      • 1970-01-01
      • 2013-06-19
      • 1970-01-01
      • 1970-01-01
      • 2020-02-17
      • 2020-12-21
      相关资源
      最近更新 更多