Rails 3 - 如何处理PG错误不完整的多字节字符

jam*_*esc 2 ruby encoding ruby-on-rails utf-8

在Rails 3.2应用程序(Ruby 1.9.2)中,我收到以下错误

在mobile_users#update中发生了PGError:

不完整的多字节字符

这些是Postgres错误我在开发和测试模式下测试时遇到类似的SQLIte错误

导致此错误的参数是(故意省略auth令牌)

  * Parameters: {"mobile_user"=>{"quiz_id"=>"1", "auth"=>"xxx", "name"=>"Joaqu\xEDn"}, "action"=>"update", "controller"=>"mobile_users", "id"=>"1", "format"=>"mobile"}
Run Code Online (Sandbox Code Playgroud)

这是作为JSON HTTP Put请求进行的,处理此问题的更新操作如下所示

  # PUT /mobile_users/1
  # PUT /mobile_users/1.xml
  def update
    @mobile_user = current_mobile_user
    @mobile_user.attributes = params[:mobile_user]

    respond_to do |format|
      if @mobile_user.save
        format.html { redirect_to(@mobile_user, :notice => 'Mobile user was successfully updated.') }
        format.json  { head :ok }
        format.mobile  { head :ok }
        format.xml  { head :ok }
      else
        format.html { render :action => "edit" }
        format.json  { render :json => @mobile_user.errors, :status => :unprocessable_entity }
        format.mobile  { render :json => @mobile_user.errors, :status => :unprocessable_entity }
        format.xml  { render :xml => @mobile_user.errors, :status => :unprocessable_entity }
      end
    end

  end
Run Code Online (Sandbox Code Playgroud)

违规字符串在上面的参数中是"Joaqu\xEDn",这是完全有效的.问题是我需要处理任何语言的所有字符集.

我假设我需要使用iconv库,但为了做到这一点,我需要检测转换为UTF8的字符集,我不知道如何做到这一点.

我也在UTF-8中获得无效的字节序列 "name"=>"p\xEDa "

mu *_*ort 5

这个:

"Joaqu\xEDn"
Run Code Online (Sandbox Code Playgroud)

是ISO-8859-1编码版本,"Joaquín"所以它不是有效的UTF-8,你的数据库是抱怨它的权利.如果可能,请修复您的移动客户端以在JSON中使用UTF-8; 如果你不能这样做那么你可以用这个修复编码:

params[:mobile_user][:name].force_encoding('iso-8859-1').encode!('utf-8')
Run Code Online (Sandbox Code Playgroud)

在服务器上.将其修复到服务器上的问题是,您必须猜测传入的编码是什么,并且您的猜测可能不正确.没有办法可靠地猜测特定字符串的编码,有rchardet,但它不适用于最新版本的Ruby,它似乎已被放弃; 您可以修复此gem以使用现代Ruby.还有一些其他的猜测库,但它们似乎也被抛弃了.

根据定义,JSON文本始终默认为Unicode和UTF-8编码:

3.  Encoding

   JSON text SHALL be encoded in Unicode.  The default encoding is
   UTF-8.
Run Code Online (Sandbox Code Playgroud)

任何向您发送不是UTF-8的JSON的客户端都会被IMO破坏,因为几乎所有客户都会认为JSON将是UTF-8.当然,可能有一个编码标题在某处指定ISO 8859-1,或者标题可能是UTF-8,即使它是ISO 8859-1.