【问题标题】:Ruby UTF8 encoding problemRuby UTF8 编码问题
【发布时间】:2010-12-02 15:52:28
【问题描述】:

我有一个 Ruby/Rails 应用程序。

我的 postgresql 数据库中有一个艺术家表,我想按名称查询。我有一些具有葡萄牙语字符等的艺术家,并且在查询他们时遇到了一些问题。

例如,一个乐队叫做 Legião Urbana。如果我从我的应用程序中使用字符串“legiã”进行查询,我会得到以下参数:

{"action"=>"search_artist", "q"=>"legi\343", "controller"=>"home"}

但是我从查询中得到一个错误

Artist.all(:conditions => "name LIKE '%#{params[:q]}%'")

PGError: ERROR:  invalid byte sequence for encoding "UTF8": 0xe32527

我应该怎么做才能转换成 UTF8 或以某种方式解决这个问题?

【问题讨论】:

    标签: ruby-on-rails ruby postgresql encoding


    【解决方案1】:

    您需要知道查询字符串中该参数的编码是什么。

    Ruby 1.9 支持使用编码标记的字符串。在 Ruby 1.9 中,您可以:

    params[:q].encoding # Rails 3 on 1.9 generally presents strings in UTF-8
    params[:q].encode('utf-8') # ask Ruby to re-encode it to UTF-8
    

    然后您需要在进行字符串插值之前将参数从该编码转换为 UTF-8(#{...} 语法)。

    或者你需要将参数作为SQL参数传递,使用字符串插值。

    当然,这带来了安全考虑,除非您知道如何正确编码文本以便在 SQL 中使用,否则您应该从不执行字符串插值来构建 SQL 字符串片段。因为带参数的 SQL 片段在 Rails 中可以快速轻松地完成,所以您应该使用它们。

    # Rails 2
    Artist.all(:conditions => ['name like ?', "%#{params[:q]}%"])
    Artist.all(:conditions => ['name like :q', { :q=> "%#{params[:q]}%" }])
    
    # Rails 3
    Artist.where('name like ?', "%#{params[:q]}")
    Artist.where('name like :q', :q => "%#{params[:q]}")
    

    SQL 注入是当您执行字符串插值和编码字符串时发生的安全问题,该方式为某些输入字符串构建正确的 SQL 片段,但不为其他输入字符串构建正确的 SQL 片段。在参数更难使用的语言/框架中,可以接受字符串插值或字符串构建(如果字符串插值或字符串构建仍然很容易),只要您详尽研究如何无论输入字符串如何,都需要对插值字符串进行编码以构建正确的 SQL 片段。因为使用 Rails 通过有序或命名参数很容易避免 SQL 注入(参见上面的四个示例),所以确保 SQL 片段都是安全的应该不会有任何问题。

    【讨论】:

    • 好吧,我更感兴趣的是编码/转换。你如何找到参数的编码?我知道 SQL 注入问题,但我只想举一个查询示例。
    • +1 表示“您需要将参数作为 SQL 参数传递,而不是使用字符串插值”。
    • 不幸的是,我对 1.8 字符串编码的情况不太熟悉。我知道在 1.8 中处理编码问题可能相当困难,如果您遇到编码问题,最好的选择是迁移到 1.9。
    【解决方案2】:

    我认为这可能会做到这一点

    require 'iconv'
    Iconv.conv("UTF8", "LATIN1", params[:q])
    

    【讨论】:

      猜你喜欢
      • 2013-03-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-07-14
      • 1970-01-01
      • 1970-01-01
      • 2012-02-21
      相关资源
      最近更新 更多