很抱歉,回复晚了,但我认为这值得更好的回答。
看这个问题有三种方式:
- 严格检查网址是否存在
- 检查您请求的 URL 是否正确
- 检查是否可以正确请求,服务器是否可以正确应答
1。严格检查URL是否存在
虽然200 表示服务器响应该 URL(因此,该 URL 存在),但回答其他状态代码并不意味着该 URL 不存在。例如,回答302 - redirected 表示该URL 存在并且正在重定向到另一个。浏览时,302 对最终用户的行为多次与200 相同。如果 URL 存在,则可以返回的其他状态代码是 500 - internal server error。毕竟,如果 URL 不存在,应用程序服务器是如何处理您的请求的,而不是简单地返回 404 - not found?
所以实际上URL不存在只有两种情况:服务器不存在或者服务器存在但找不到给定的URL路径不存在。 因此,检查 URL 是否存在的唯一方法是检查服务器是否响应并且返回码不是 404。 下面的代码就是这样做的。
require "net/http"
def url_exist?(url_string)
url = URI.parse(url_string)
req = Net::HTTP.new(url.host, url.port)
req.use_ssl = (url.scheme == 'https')
path = url.path if url.path.present?
res = req.request_head(path || '/')
res.code != "404" # false if returns 404 - not found
rescue Errno::ENOENT
false # false if can't find the server
end
2。检查您请求的 URL 是否正确
但是,大多数时候我们并不关心是否存在 URL,而是我们是否可以访问它。幸运的是查看HTTP status codes 家族,即4xx 家族,它说明客户端错误(因此,您身边的错误,这意味着您没有正确请求页面,没有权限或其他任何内容)。这是检查您是否可以访问此页面的一个很好的错误。来自维基:
4xx 类状态代码适用于客户端似乎出错的情况。除了响应 HEAD 请求时,服务器应该包含一个实体,其中包含对错误情况的解释,以及它是临时情况还是永久情况。这些状态码适用于任何请求方法。用户代理应该向用户显示任何包含的实体。
所以下面的代码确保网址存在并且可以访问:
require "net/http"
def url_exist?(url_string)
url = URI.parse(url_string)
req = Net::HTTP.new(url.host, url.port)
req.use_ssl = (url.scheme == 'https')
path = url.path if url.path.present?
res = req.request_head(path || '/')
if res.kind_of?(Net::HTTPRedirection)
url_exist?(res['location']) # Go after any redirect and make sure you can access the redirected URL
else
res.code[0] != "4" #false if http code starts with 4 - error on your side.
end
rescue Errno::ENOENT
false #false if can't find the server
end
3。检查是否可以正确请求,服务器是否可以正确回答
就像4xx 系列检查您是否可以访问该 URL,5xx 系列检查服务器在回答您的请求时是否有任何问题。大多数时候这个系列的错误是服务器本身的问题,希望他们正在努力解决它。如果您现在需要能够访问该页面并获得正确答案,则应确保该答案不是来自4xx 或5xx 家庭,如果您被重定向,则重定向页面回答正确。与(2)非常相似,您可以简单地使用以下代码:
require "net/http"
def url_exist?(url_string)
url = URI.parse(url_string)
req = Net::HTTP.new(url.host, url.port)
req.use_ssl = (url.scheme == 'https')
path = url.path if url.path.present?
res = req.request_head(path || '/')
if res.kind_of?(Net::HTTPRedirection)
url_exist?(res['location']) # Go after any redirect and make sure you can access the redirected URL
else
! %W(4 5).include?(res.code[0]) # Not from 4xx or 5xx families
end
rescue Errno::ENOENT
false #false if can't find the server
end