ruby-on-rails - rails : What's a good way to validate links (URLs)?

标签 ruby-on-rails ruby regex validation url

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

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

最佳答案

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

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

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

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

http://invalid##host.com

但它会允许

http://invalid-host.foo

如果您考虑现有的 TLD,那是一个有效的主机,但不是一个有效的域。实际上,如果您想验证主机名而不是域,该解决方案将起作用,因为以下是有效的主机名

http://host.foo

还有下面的

http://localhost

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

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

如果要验证 URI/URL 的格式,则可能需要使用正则表达式。不要搜索一个,而是使用内置的 Ruby URI.parse 方法。

require 'uri'

def valid_url?(uri)
  uri = URI.parse(uri) && uri.host
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.nil?
rescue URI::InvalidURIError
  false
end

当然,您可以对这种方法进行大量改进,包括检查路径或方案。

最后但同样重要的是,您还可以将此代码打包到验证器中:

class HttpUrlValidator < ActiveModel::EachValidator

  def self.compliant?(value)
    uri = URI.parse(value)
    uri.is_a?(URI::HTTP) && !uri.host.nil?
  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

关于ruby-on-rails - rails : What's a good way to validate links (URLs)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7167895/

相关文章:

ruby-on-rails - Rails - 不同的时区来限制每日帖子

javascript - Rails history.pushState 通过 AJAX 显示 URL

ruby-on-rails - 安装 posix spawn 时出现 UTF-8 设置问题

用于自定义函数的 Java 正则表达式

ruby-on-rails - Capistrano 与 Rake 有什么关系?

ruby-on-rails - 通过 OmniAuth 传递参数

ruby-on-rails - 如何使用 JBuilder 从数组中完全删除一个空元素

ruby-on-rails - rails install - ERROR ... executing gem ... (OpenSSL::SSL::SSLError) SSL_connect ... read server hello A: 错误的版本号

regex - 代码格式 - 减轻不可读的大正则表达式的方法?

php - preg_split 字符串不在单引号之间