Rails:验证链接 (URL) 的好方法是什么?

2023-11-24

我想知道如何最好地验证 Rails 中的 URL。我正在考虑使用正则表达式,但不确定这是否是最佳实践。

而且,如果我要使用正则表达式,有人可以向我推荐一个吗?我对正则表达式还是新手。


验证 URL 是一项棘手的工作。这也是一个非常广泛的要求。

你到底想做什么?您想要验证 URL 的格式、是否存在或者什么?有多种可能性,具体取决于您想要做什么。

正则表达式可以验证 URL 的格式。但即使是复杂的正则表达式也无法确保您处理的是有效的 URL。

例如,如果您采用简单的正则表达式,它可能会拒绝以下主机

http://invalid##host.com

但它会允许

http://invalid-host.foo

这是一个有效的主机,但如果您考虑现有的 TLD,则不是一个有效的域。事实上,如果您想验证主机名而不是域,则该解决方案可行,因为以下是有效的主机名

http://host.foo

还有下面这个

http://localhost

现在,让我给你一些解决方案。

如果您想验证域,那么您需要忘记正则表达式。目前可用的最佳解决方案是公共后缀列表,该列表由 Mozilla 维护。我创建了一个 Ruby 库来根据公共后缀列表解析和验证域,它被称为公共后缀.

如果您想验证 URI/URL 的格式,那么您可能需要使用正则表达式。不用搜索,而是使用内置的 RubyURI.parse method.

require 'uri'

def valid_url?(uri)
  uri = URI.parse(uri) && uri.host.present?
rescue URI::InvalidURIError
  false
end

您甚至可以决定使其更具限制性。例如,如果您希望 URL 是 HTTP/HTTPS URL,那么您可以使验证更加准确。

require 'uri'

def valid_url?(url)
  uri = URI.parse(url)
  uri.is_a?(URI::HTTP) && uri.host.present?
rescue URI::InvalidURIError
  false
end

当然,您可以对此方法应用大量改进,包括检查路径或方案。

最后但并非最不重要的一点是,您还可以将此代码打包到验证器中:

class HttpUrlValidator < ActiveModel::EachValidator

  def self.compliant?(value)
    uri = URI.parse(value)
    uri.is_a?(URI::HTTP) && uri.host.present?
  rescue URI::InvalidURIError
    false
  end

  def validate_each(record, attribute, value)
    unless value.present? && self.class.compliant?(value)
      record.errors.add(attribute, "is not a valid HTTP URL")
    end
  end

end

# in the model
validates :example_attribute, http_url: true

新 URI 版本的注意事项(即 0.12.1)

.present? / .blank?将是验证主机的更准确方法,而不是使用uri.host.nil?要不就if uri.host以前(即 URI v 0.11)。

URI.parse("https:///394") 的示例:

  • 新的 URI 版本(0.12),host将返回一个空字符串,并且/394成为一条路径。 #<:https>
  • 旧 URI 版本 (0.11),host将返回一个空字符串,并且/394也成为一条路。 #<:https>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Rails:验证链接 (URL) 的好方法是什么? 的相关文章

随机推荐