1

我在 Safari 和 Firefox 中显示 UTF-8 字符串时遇到问题,以便通过 X-Message 标头在 Rails 中发送 flash 消息,用于 ajax 请求,如下所示:

class ApplicationController < ActionController::Base
  def flash_to_headers
       return unless request.xhr?
       message = flash_message
       message = "#{message.join("','")}" if message.is_a?(Array)
       response.headers['X-Message'] = message
       response.headers["X-Message-Type"] = flash_type.to_s

       flash.discard # don't want the flash to appear when you reload page
   end

   def flash_message
       [:red, :warning, :notice, :success, nil].each do |type|
         return "" if type.nil?
         return flash[type] unless flash[type].blank?
       end
   end

   def flash_type
       [:red, :warning, :notice, :success, nil].each do |type|
         return "" if type.nil?
         return type unless flash[type].blank?
       end
   end

处理标头的Javascript:

var fade_flash = function() {
    $(".flash_alert").fadeIn("fast");
    $(".flash_alert").delay(10000).fadeOut("slow");
};

var show_ajax_message = function(msg, type) {
    $(".flash_message").html('<div class="flash_alert hidden flash_'+type+'">'+msg+'</div>');
    fade_flash();
};

$( document ).ajaxComplete(function(event, request) {
    var msg = request.getResponseHeader('X-Message');
    var type = request.getResponseHeader('X-Message-Type');
    if (msg) {
      show_ajax_message(msg, type);
    }

});

在我添加了支持中文的 l18n 语言环境之前,这一直很好用。在 Chrome 中它仍然有效,但在 Safari 和 Firefox 中,flash 消息不再正确显示。

例如:像这样的消息:“投注金额”比你的余额多”会在 Chrome 中正常显示,但在 Safari 和 Firefox 中会显示为:“âææ¨éé¢â æ¯ä½ çä½é¢å¤”。

你可以在https://ice-dice.com看到这个 bug 的现场演示。 只需在 Chinese locale 下点击 roll,你可以看到 flash 消息是不正确的,除非使用 chrome。甚至引号也没有在英语语言环境中正确显示。

在此先感谢您的帮助!

4

1 回答 1

0

HTTP 标头由 RFC 2616 指定以携带 ISO-8859-1 数据。Safari 和 Firefox 正在做正确的事情。根据 HTTP 标准,不能将中文字符放入 HTTP 标头值中。

这里的浏览器行为不一致(Opera 也使用 UTF-8,而 IE 使用任何语言环境的 ANSI 代码页),因此在 HTTP 标头中使用非 ASCII 字符是不安全的。

如果必须使用标头,通常的解决方法是在每一端应用临时编码,通常是 URL 编码或基于 UTF-8 字节的 base64 编码。但通常最好不要将任意数据包装在 HTTP 标头中;而是将其放入体内。

于 2013-10-02T21:01:14.903 回答