URLをエンコードした状態で保存する場合、URI.encode
のような処理でエンコードすることが可能ですが、もし入力されたURLがエンコード済の場合、二重エンコードとなってしまい正しいURLではなくなってしまいます。この記事ではエンコード済かどうかの確認方法をまとめました。
結論
URLをデコードした文字列が元の文字列と一致する場合エンコードされていない状態、一致しない場合はエンコード済という判断が可能です。
Addressable::URI.unescape(url) != url ? Addressable::URI.encode(url) : url
動作確認
Ruby 2.7.0からURI.encode
がobsoleteになっているため、Addressable
を使用しようと思います。
例としてAmazonのURLを使用すると以下のような結果になります。URLエンコードされていない場合、Addressable::URI.unescape
を何度行っても文字列が変わらないことを利用しています。
require "addressable/uri"
# URLエンコード前
no_encoded_url = 'https://www.amazon.co.jp/Echo-Dot-エコードット-第4世代-時計付きスマートスピーカー-with-Alexa-グレーシャーホワイト/dp/B084J4TR39'
Addressable::URI.unescape(no_encoded_url)
=> "https://www.amazon.co.jp/Echo-Dot-エコードット-第4世代-時計付きスマートスピーカー-with-Alexa-グレーシャーホワイト/dp/B084J4TR39"
Addressable::URI.unescape(no_encoded_url) == no_encoded_url
=> true
# URLエンコード済
encoded_url = 'https://www.amazon.co.jp/Echo-Dot-%E3%82%A8%E3%82%B3%E3%83%BC%E3%83%89%E3%83%83%E3%83%88-%E7%AC%AC4%E4%B8%96%E4%BB%A3-%E6%99%82%E8%A8%88%E4%BB%98%E3%81%8D%E3%82%B9%E3%83%9E%E3%83%BC%E3%83%88%E3%82%B9%E3%83%94%E3%83%BC%E3%82%AB%E3%83%BC-with-Alexa-%E3%82%B0%E3%83%AC%E3%83%BC%E3%82%B7%E3%83%A3%E3%83%BC%E3%83%9B%E3%83%AF%E3%82%A4%E3%83%88/dp/B084J4TR39'
Addressable::URI.unescape(encoded_url)
=> "https://www.amazon.co.jp/Echo-Dot-エコードット-第4世代-時計付きスマートスピーカー-with-Alexa-グレーシャーホワイト/dp/B084J4TR39"
Addressable::URI.unescape(encoded_url) == encoded_url
=> false
Addressable::URI.unescape(encoded_url) == no_encoded_url
=> true