Rails: リンク (URL) を検証する良い方法は何ですか? 質問する

Rails: リンク (URL) を検証する良い方法は何ですか? 質問する

Rails で URL を検証する最適な方法を知りたいです。正規表現を使用することを考えていましたが、これがベストプラクティスかどうかはわかりません。

また、正規表現を使用する場合、誰か私に提案してもらえますか? 私はまだ正規表現の初心者です。

ベストアンサー1

URL の検証は難しい作業です。また、非常に広範囲な要求でもあります。

具体的に何をしたいですか? URL の形式、存在、またはその他のものを検証したいですか? 何をしたいかに応じて、いくつかの可能性があります。

正規表現は URL の形式を検証できます。ただし、複雑な正規表現であっても、有効な URL を扱っていることを保証することはできません。

例えば、単純な正規表現を使用すると、次のホストは拒否される可能性があります。

http://invalid##host.com

しかし、それは

http://invalid-host.foo

これは有効なホストですが、既存のTLDを考慮すると有効なドメインではありません。実際、次のものは有効なホスト名であるため、ドメインではなくホスト名を検証したい場合にこの解決策は機能します。

http://host.foo

同様に次のものも

http://localhost

さて、いくつかの解決策をお伝えしましょう。

ドメインを検証したい場合、正規表現は忘れてください。現時点で利用できる最良の解決策は、Mozillaが管理するPublic Suffix Listです。私は、Public Suffix Listに対してドメインを解析および検証するためのRubyライブラリを作成しました。パブリックサフィックス

URI/URL の形式を検証したい場合は、正規表現を使用することをお勧めします。正規表現を検索する代わりに、組み込みの RubyURI.parseメソッドを使用します。

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?/ は、以前 (つまり URI v 0.11)または を.blank?使用する代わりに、ホストを検証するより正確な方法です。uri.host.nil?if uri.host

URI.parse("https:///394") の例:

  • 新しい URI バージョン (0.12) はhost空の文字列を返し、/394パスになります。#<URI::HTTPS https:///394>
  • 古い URI バージョン (0.11) では、host空の文字列が返され、/394パスにもなります。#<URI::HTTPS https:/394>

おすすめ記事