2013-07-17 79 views
0

我有一点我的Ruby/Rails(Ruby 2.0.0p195,Rails 3.2.13)项目,作为代理工作;也就是说,您将它传递给一个URL,它会跳出并提取该页面,并将其呈现给您。这通常按预期工作,但似乎困扰某些字符(如è)。Rails/unicode问题

控制器的简化版本是这样的:

class HomeController < ApplicationController 
    def geoproxy 
    require 'net/http' 
    require 'timeout' 

    rawurl = CGI::unescape(params[:url]) 

    fixedurl = rawurl.gsub('\\', '%5C') # Escape backslashes... why oh why???!? 
    r = nil; 

    status = 200 
    content_type = '' 

    begin 
     Timeout::timeout(15) {  # Time, in seconds 

     if request.get? then 
      res = Net::HTTP.get_response(URI.parse(fixedurl)) 

      status = res.code # If there was an error, pass that code back to our caller 
      @page = res.body.encode('UTF-8') 
      content_type = res['content-type']  
     end 
     } 

    rescue Timeout::Error 
     @page = "TIMEOUT" 
     status = 504 # 504 Gateway Timeout We're the gateway, we timed out. Seems logical. 
    end 

    render :layout => false, :status => status, :content_type => content_type 
    end 
end 

的相应的视图是很简单:

<%= raw @page %> 

当我使用这个代理来获取包含E(例如)XML,我得到以下错误:

Encoding::UndefinedConversionError in HomeController#geoproxy 
"\xE8" from ASCII-8BIT to UTF-8 

在下面的行会出现此错误:

@page = res.body.encode('UTF-8') 

如果我删除.encode(),错误是解决了,但我的XML包含一个占位符,而不是电子。

如何让我的项目正确显示XML?

回答

1

你能否检查下面的代码是否适合你?我能够用它解决类似的问题。

@page = res.body.force_encoding('Windows-1254').encode('UTF-8') 
+1

让我非常震惊和惊讶,你的建议奏效了。另一种也可以工作的方法是,我更喜欢出于某种原因,这是:@page = res.body.force_encoding('ISO-8859-1')。encode('UTF-8')。你有什么想法_why_这有效吗? – Watusimoto

+0

不同的字符集可能表示相同的字符。在这种情况下,由于两个字符集都能够将字符'è'转换为'00E8'或'\ xE8',这两种编码都会产生相同的结果是正常的。也可能有其他字符集可以做到这一点。你只要确定你使用的编码类型能够处理你从'res.body'中得到的字符类型。 –

+0

我理解这一点,但不是为什么要对一个字符集进行force_encoding,然后以UTF编码进行重新编码。我知道Ruby默认为UTF-8,所以我不确定为什么必须设置编码,也不知道为什么简单地用UTF-8编码不起作用。 – Watusimoto