为Net :: HTTP指定字符编码

当我发出此HTTP请求时:

Net::HTTP.get_response('www.telize.com',"/geoip/190.88.39.27").body => "{\"timezone\":\"America\\/Curacao\",\"isp\":\"United Telecommunication Services (UTS)\",\"country\":\"Cura\xE7ao\",\"dma_code\":\"0\",\"region_code\":\"00\",\"area_code\":\"0\",\"ip\":\"190.88.39.27\",\"asn\":\"AS11081\",\"continent_code\":\"NA\",\"city\":\"Willemstad\",\"longitude\":-68.9167,\"latitude\":12.1,\"country_code\":\"CW\",\"country_code3\":\"CUW\"}\n" 

它返回一个JSON主体,但注意国家:\“country \”:\“Cura \ xE7ao \”。 响应机构实际上应该是这样的:“country”:“Curaçao”。 看起来Net :: HTTP假设这是ASCII-8BIT:

 Net::HTTP.get_response('www.telize.com',"/geoip/190.88.39.27").body.encoding => Encoding:ASCII-8BIT 

但事实并非如此。 如何在发出请求时告诉Net :: HTTP使用哪种字符编码?

正如Tin Man所确定的那样,“\ xE7”是LEDIN LATIN SMALL LETTER C WITH CEDILLA的latin-1编码,据我LATIN SMALL LETTER C WITH CEDILLA ,它不是一个有效的json编码。

但是……一旦你知道编码,就可以将它从ruby的ASCII-8BIT(这意味着ruby认为数据是二进制的,即未编码的)改为UTF-8,如下所示:

 require 'net/http' server_encoding = "ISO-8859-1" resp = Net::HTTP.get_response('www.telize.com',"/geoip/190.88.39.27") json = resp.body.force_encoding(server_encoding).encode("UTF-8") puts json --output:-- {"timezone":"America\/Curacao","isp":"United Telecommunication Services UTS)","country":"Curaçao","dma_code":"0","region_code":"00","area_code":"0", "ip":"190.88.39.27","asn":"AS11081","continent_code":"NA","city":"Willemstad", "longitude":-68.9167,"latitude":12.1,"country_code":"CW","country_code3":"CUW"} 

看起来Net :: HTTP假设这是ASCII-8BIT

Net :: HTTP将数据标记为二进制/ ASCII-8BIT,即数据没有编码,并留给您了解如何解释数据。

你无法告诉服务器使用什么编码,但你可以问它认为文件的编码是什么,然后传递那个Net :: HTTP。

看看head方法:

 response = nil Net::HTTP.start('www.telize.com',80) { |http| response = http.head('/geoip/190.88.39.27') } response.each_header { |h| p "#{ h } => #{ response[h] }" } 

运行它告诉你各种标题的内容:

 "server => nginx" "date => Thu, 12 Jun 2014 23:42:16 GMT" "content-type => application/json; charset=iso-8859-1" "connection => close" 

content-type值是您想要的:

 response['content-type'].split('=').last # => "iso-8859-1" 

请注意,服务器很少进行一致性检查,以查看它被告知使用的编码是否与它所服务的文件匹配。 这意味着您收到的内容可能与服务器所说的内容大相径庭,而且,此时,您完全可以自己弄清楚它到底是什么,特别是当文件混合编码时。 欢迎来到野外和毛茸茸的互联网。