在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"}
这是作为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
违规字符串在上面的参数中是“Joaqu \ xEDn”,这是完全有效的。 问题是我需要处理任何语言的所有字符集。
我假设我需要使用iconv库,但为了做到这一点,我需要检测转换为UTF8的字符集,并且我不知道如何做到这一点。
我也在"name"=>"p\xEDa "
答案 0 :(得分:5)
此:
"Joaqu\xEDn"
是"Joaquín"
的ISO-8859-1编码版本,因此它不是有效的UTF-8,您的数据库是正确的抱怨它。如果可能,请修复您的移动客户端以在JSON中使用UTF-8;如果你不能这样做那么你可以用这个来修复编码:
params[:mobile_user][:name].force_encoding('iso-8859-1').encode!('utf-8')
在服务器上。将其修复到服务器上的问题是,您必须猜测传入的编码是什么,并且您的猜测可能不正确。没有办法可靠地猜测特定字符串的编码,有rchardet但它不适用于最新版本的Ruby,它似乎已被放弃;您可以修复此gem以使用现代Ruby。还有一些其他的猜测库,但它们似乎都被抛弃了。
默认情况下,JSON文本始终为by definition,Unicode和UTF-8编码:
3. Encoding
JSON text SHALL be encoded in Unicode. The default encoding is
UTF-8.
任何向您发送不是UTF-8的JSON的客户端都会被IMO破坏,因为几乎所有客户都会认为JSON将是UTF-8。当然,可能有某个编码头指定ISO 8859-1,或者标题可能是UTF-8,即使它是ISO 8859-1。
答案 1 :(得分:4)
我在解析文件时遇到了用户生成数据的相同问题,并以这种方式解决了这个问题:
require 'iconv'
....
line = Iconv.conv('UTF-8//IGNORE', 'UTF-8', line)
#now variable line has valid utf-8 data
您可以尝试覆盖'name'setter,以便它删除非utf8字符:
def name=(name)
write_attribute(:name, Iconv.conv('UTF-8//IGNORE', 'UTF-8', name))
end