2013-10-30 65 views
2

更新:经过进一步调查后,我设法将问题缩小到json编码器。直接传递输入工作正常,但通过MultiJson.encode是什么导致了这个问题。发送到服务器的Unicode字符作为垃圾返回

我通过卷曲发送跟进到一个RESTful Web服务:

$ curl -v -X POST "http://my/url" -d "{\"body\": \"\"}" 

,你可能无法看到的是Credit Card表情符号,这是U + 1F4B3的字符。

我从服务回馈的反应基本上是:

< HTTP/1.1 200 OK 
< Date: Wed, 30 Oct 2013 02:38:04 GMT 
< Content-Type: application/json;charset=utf-8 
< Content-Length: 266 
< Connection: close 
< 
{ [data not shown] 
100 304 100 266 100 38 936 133 --:--:-- --:--:-- --:--:-- 936 
* Closing connection 0 
{ 
    "body": "\uf4b3" 
} 

该编码的字符不符合我送什么,我希望是把它交给返回(在这种情况下)。

我可以访问服务器的源代码。它建立在Ruby,Sinatra和ActiveRecord之上。有响应之前正在进行处理的一定量的被发送:通过ERB::Util.html_escape

  • 然后

    • 首先,内容传递,一系列regexs的经由str.gsub!(reg, " ### ")
    • 最后施加时,响应经由返回MultiJson.encode

    我不是Ruby的人,但可以提供额外的细节,如果有必要。希望有人指出我正确的方向。谢谢!

  • +1

    不顺心的事在U + 1F4B3的编码。使用'\ u'符号,它应该显示为两个单元(代理对),但显然转换它的软件不准备处理非BMP字符(字符> U + FFFF),并且错误地将1F4B3屏蔽到F483 。 –

    +0

    你没有告诉我们的东西:你的“服务器”是做什么的? :)它是否回应您发送的内容? –

    +0

    @JohnBachir它创建一个对象来清理数据并将其存储在数据库中。它将所创建的对象序列化为JSON。 – twaddington

    回答

    0

    我们能够通过迁移到不同的JSON编码引擎来解决这个问题:

    get "/foo" do 
        resp = "" 
    
        puts MultiJson.adapter() 
        puts MultiJson.dump(resp) # Fails 
    
        MultiJson.engine = :jrjackson 
        puts MultiJson.adapter() 
        puts MultiJson.dump(resp) # Succeeds 
    end 
    
    0

    首先要检查的是,角色是否按照您认为的方式进入应用程序的主体。 Ruby有一个默认的“内部”和“外部”编码的概念。一旦一个字符串通过各种IO进入,由于各种原因,它可能会或可能不会有预期的编码,因为它传递了。

    这并不是说很难管理或混淆 - 这一切都很简单,但我只是指出所有这些事情都可能被配置/更改。

    要看你开始的是什么,只要你可以在你的程序中,一旦你有输入,检查它的编码。

    params[:foo].encoding 
    => #<Encoding:UTF-8> 
    

    如果它不是utf-8,那么你需要设置你的环境和/或你的IO机制来使用utf-8。

    从ruby 2.0开始,默认的编码是 - 赞美众神 - utf8。所以,如果你不使用ruby 2.0并且能够升级到这一点。

    如果您没有该选项,那么您需要设置默认编码。虽然it seems sinatra sets it to utf-8