Ruby Net :: HTTP – 遵循301重定向

我的用户提交了url(混合在mixcloud.com上),我的应用程序使用它们来执行网络请求。

一个好的url返回200状态代码:

uri = URI.parse("http://www.mixcloud.com/ErolAlkan/hard-summer-mix/") request = Net::HTTP.get_response(uri)( # 

但是如果你忘记了斜杠,那么我们原本不错的url会返回301:

 uri = "http://www.mixcloud.com/ErolAlkan/hard-summer-mix" # 

404的情况也是如此:

 # bad path returns a 404 "http://www.mixcloud.com/bad/path/" # bad path minus trailing slash returns a 301 "http://www.mixcloud.com/bad/path" 
  1. 如何“向下钻取”301以查看它是否将我们带到有效资源或错误页面?
  2. 是否有一个工具可以全面概述特定域可能适用于其URL的规则?

如果您没有完全按照Web服务器的预期输入URL,那么301重定向是相当常见的。 它们的发生频率比您想象的要频繁得多,您在浏览时通常不会注意到它们,因为浏览器会自动为您完成所有操作。

我想到了两种选择:

1:使用open-uri

open-uri自动处理重定向。 所以你需要做的就是:

 require 'open-uri' ... response = open('http://xyz...').read 

如果您在HTTP和HTTPS之间重定向时遇到问题,那么请查看解决方案:
Ruby open-uri重定向被禁止

2:使用Net::HTTP处理重定向

 def get_response_with_redirect(uri) r = Net::HTTP.get_response(uri) if r.code == "301" r = Net::HTTP.get_response(URI.parse(r.header['location'])) end r end 

如果你想更聪明,你可以尝试在获得404响应时添加或删除丢失的反斜杠到URL。 您可以通过创建get_response_smart类的方法来实现这一点,该方法除了重定向之外还处理此URL。

我无法弄清楚如何评论接受的答案(这个问题可能会被关闭),但我应该注意到r.header现在已经过时了,所以r.header['location']应该被r['location'] (根据https://stackoverflow.com/a/6934503/1084675 )

这是我提出的代码(来自不同的例子),如果有太多的重定向将会挽救(请注意,ensure_success是可选的):

 require "net/http" require "uri" class Net::HTTPResponse def ensure_success unless kind_of? Net::HTTPSuccess warn "Request failed with HTTP #{@code}" each_header do |h,v| warn "#{h} => #{v}" end abort end end end def do_request(uri_string) response = nil tries = 0 loop do uri = URI.parse(uri_string) http = Net::HTTP.new(uri.host, uri.port) request = Net::HTTP::Get.new(uri.request_uri) response = http.request(request) uri_string = response['location'] if response['location'] unless response.kind_of? Net::HTTPRedirection response.ensure_success break end if tries == 10 puts "Timing out after 10 tries" break end tries += 1 end response end 

rest-client遵循GETHEAD请求的重定向,无需任何其他配置。 它非常好用。

  • 对于200到207之间的结果代码,将返回RestClient :: Response
  • 对于结果代码301,302或307,如果请求是GET或HEAD,则将遵循重定向
  • 对于结果代码303,将遵循重定向并将请求转换为GET

用法示例:

 require 'rest-client' RestClient.get 'http://example.com/resource' 

rest-client README还提供了一个使用POST请求进行重定向的示例:

 begin RestClient.post('http://example.com/redirect', 'body') rescue RestClient::MovedPermanently, RestClient::Found, RestClient::TemporaryRedirect => err err.response.follow_redirection end 

不确定是否有人正在寻找这个确切的解决方案,但如果您尝试下载图像http / https并将其存储到变量

 require 'open_uri_redirections' require 'net/https' web_contents = open('file_url_goes_here', :ssl_verify_mode => OpenSSL::SSL::VERIFY_NONE, :allow_redirections => :all) {|f| f.read } puts web_contents