Bir URL'yi doğrulamak zor bir iştir. Aynı zamanda çok geniş bir talep.
Tam olarak ne yapmak istiyorsun? URL'nin biçimini, varlığını veya ne olduğunu doğrulamak istiyor musunuz? Ne yapmak istediğinize bağlı olarak birkaç olasılık vardır.
Normal bir ifade, URL'nin biçimini doğrulayabilir. Ancak karmaşık bir düzenli ifade bile geçerli bir URL ile uğraştığınızı garanti edemez.
Örneğin, basit bir düzenli ifade alırsanız, muhtemelen aşağıdaki ana bilgisayarı reddedecektir
http://invalid##host.com
ama izin verecek
http://invalid-host.foo
bu geçerli bir ana bilgisayardır, ancak mevcut TLD'leri dikkate alırsanız geçerli bir etki alanı değildir. Aslında, çözüm, etki alanını değil ana bilgisayar adını doğrulamak istiyorsanız işe yarar çünkü aşağıdaki geçerli bir ana bilgisayar adıdır
http://host.foo
yanı sıra bir sonraki
http://localhost
Şimdi size bazı çözümler vereyim.
Bir alanı doğrulamak istiyorsanız, normal ifadeleri unutmanız gerekir. Şu anda mevcut olan en iyi çözüm, Mozilla tarafından sağlanan bir liste olan Genel Son Ek Listesi'dir. Etki alanlarını Genel Son Ek Listesi'ne göre ayrıştırmak ve doğrulamak için bir Ruby kitaplığı oluşturdum ve adı PublicSuffix .
Bir URI / URL'nin biçimini doğrulamak istiyorsanız, normal ifadeler kullanmak isteyebilirsiniz. Birini aramak yerine yerleşik Ruby URI.parse
yöntemini kullanın.
require 'uri'
def valid_url?(uri)
uri = URI.parse(uri) && !uri.host.nil?
rescue URI::InvalidURIError
false
end
Hatta daha kısıtlayıcı hale getirmeye bile karar verebilirsiniz. Örneğin, URL'nin bir HTTP / HTTPS URL'si olmasını istiyorsanız, doğrulamayı daha doğru hale getirebilirsiniz.
require 'uri'
def valid_url?(url)
uri = URI.parse(url)
uri.is_a?(URI::HTTP) && !uri.host.nil?
rescue URI::InvalidURIError
false
end
Elbette, bir yolu veya şemayı kontrol etmek de dahil olmak üzere bu yönteme uygulayabileceğiniz tonlarca iyileştirme vardır.
Son olarak, bu kodu bir doğrulayıcıya da paketleyebilirsiniz:
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