【问题标题】:Rails: Validate that a link won't create a 404 errorRails:验证链接不会产生 404 错误
【发布时间】:2011-03-25 13:28:42
【问题描述】:

所以我有一个网络应用程序,用户和非用户都可以在其中提交内容链接。我的网络应用程序是一个用户接收内容捐赠的网站,因此我确保用户在接收捐赠之前验证他们是网站的所有者。

因此,当用户从他们自己的网站提交链接时,他们会得到一个表单,其中包含他们已注册和验证的所有网站的选择字段。如果用户为其他人的网站提交链接,他们会得到一个表单,其中它只是 :unclaimed_domain 的文本字段(不在数据库中,而是用作 find_or_create 方法的一部分的 attr_accessor)

...我希望这是足够的背景信息。

我正在尝试实现一项功能,以防止用户提交被证明是 404 错误的链接。

这是我目前不满意的验证(验证永远不会通过):

  require 'net/http'
  require 'nokogiri'
  require 'open-uri'

    def should_not_have_a_404_link
        if unclaimed_domain != nil || unclaimed_domain != "" #attr_accessor field
            domain = unclaimed_domain
        else
            domain = Website.find_by_website_id(self.website_id).domain #select_field
        end
        response = Net::HTTP.start(domain, 80) {|http| http.head("/self.link") }
        if response.code == "404"
            errors.add(:link, "404 Error")
        end         
    end

我尝试的另一种方法是:

def should_not_have_a_404_link
    if unclaimed_domain != nil || unclaimed_domain != "" #attr_accessor field
        domain = unclaimed_domain
    else
        domain = Website.find_by_website_id(self.website_id).domain #select_field
    end
   begin
     Nokogiri::HTML(open("http://#{domain}/self.link"))
   rescue
     errors.add(:link, "404 error")
   end
 end

这在提交全新网站时有效,但不适用于现有网站。

我还有一个名为 :make_full_link 的回调,这可能是问题的一部分

    before_create :make_full_link 
    before_update :make_full_link

   def make_full_link
        website = Website.find(website_id)
        unless self.link.index("http://#{website.domain}")        
        old_link = self.link
        self.link = "http://#{website.domain}/#{old_link}"
        end
    end
end

有什么想法吗?

【问题讨论】:

    标签: ruby-on-rails validation callback


    【解决方案1】:

    我想我可以通过托管我自己的超慢 http 服务器来锁定您的 rails 进程(您网站上的所有动态内容),该服务器每隔几分钟发送一两个字符并提交三、四个或十个请求。它会占用您所有的队列处理器,并且无法提供更多动态内容。

    我建议为您的请求添加一个超时时间(如果您真的想执行在线有效性检查),或者只是将有效性检查移动到一个用 cron 或按需或其他方式运行的离线任务。

    此外,您只是在检查您没有收到 200 响应代码,但例如301302307 都可以,只是需要客户多处理。

    建议不要将"404 error" 添加到您的errors,而是添加实际 响应代码。如果例如,那会更有用。已实施访问控制以允许每个网络块访问,并且您的主机正在接收403 响应,但向用户报告它正在收到404 响应。这些是非常不同的事情,应该正确报告。 (你有没有看到无用的IE错误信息“对不起,无法连接到远程主机,可能是离线,可能是防火墙,可能DNS不存在,可能你没有连接到互联网任何更多”?我讨厌它,它没有详细说明如何解决这种情况。)

    【讨论】:

    • 感谢您的建议,我将该行更改为“if response.code == '404'”。我不希望消除所有无效链接,只是消除其中的大部分,以免它们堵塞数据库。顺便说一句,您将如何处理这些超时?
    • 酷,net/http 库提供了一个 read_timeout=(),看起来它将提供足够好的超时支持:ruby-doc.org/stdlib/libdoc/net/http/rdoc/classes/Net/…
    • 嗯,超时似乎不起作用。这可能是我做错的其他事情。
    猜你喜欢
    • 1970-01-01
    • 2012-10-22
    • 2018-07-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-08-22
    • 2013-08-15
    相关资源
    最近更新 更多