Rails で URL を検証する最善の方法は何かと考えていました。正規表現を使用することを考えていましたが、これがベストプラクティスかどうかわかりません。
また、正規表現を使用する場合、誰かが正規表現を提案してもらえますか?私はまだ正規表現を使い始めたばかりです。
URL の検証は難しい作業です。それは非常に幅広い要求でもあります。
具体的に何がしたいのですか? URL の形式、存在、またはその他を検証しますか?やりたいことに応じて、いくつかの可能性があります。
正規表現を使用して URL の形式を検証できます。ただし、複雑な正規表現であっても、有効な URL を扱っていることを保証することはできません。
たとえば、単純な正規表現を使用すると、次のホストが拒否される可能性があります。
http://invalid##host.com
しかしそれは許可します
http://invalid-host.foo
これは有効なホストですが、既存の TLD を考慮すると有効なドメインではありません。実際、次のホスト名は有効なホスト名であるため、ドメインではなくホスト名を検証したい場合、この解決策は機能します。
http://host.foo
次のものも同様に
http://localhost
さて、いくつかの解決策を紹介します。
ドメインを検証する場合は、正規表現を忘れる必要があります。現時点で利用可能な最良のソリューションは、Mozilla が管理するリストであるパブリック サフィックス リストです。私はパブリック サフィックス リストに対してドメインを解析して検証するための Ruby ライブラリを作成しました。これは PublicSuffix と呼ばれます。
URI/URL の形式を検証する場合は、正規表現を使用することをお勧めします。検索する代わりに、組み込みの Ruby URI.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.host.nil を使用する代わりに、ホストを検証するより正確な方法はありますか?または、uri.host が以前の場合 (つまり、URI v 0.11)。
URI.parse(“https:///394”) の例: