回答:
いくつかの小さな違いがありましたが、重要な点は、Ruby 1.9.2 URI.escape
では非推奨になっていることです。そのため、CGI::escape
またはERB :: Util.url_encodeを使用してください。
長い議論があるルビー・コア上にも言及し、それらの興味のためにWEBrickに:: HTTPUtils.escapeとWEBrickに:: HTTPUtils.escape_formが。
ERB::Util.url_encode
、適切に使用している%20
スペースのために
斧と剣の違いは何ですか?どちらを使うべきですか?まあそれはあなたが何をする必要があるかに依存します。
URI.escape
文字列(URL)をいわゆる「パーセントエンコーディング」にエンコードすることになっていた。
CGI::escape
は、CGI仕様に由来しています。CGI仕様では、Webサーバーとアプリケーションの間でデータをエンコード/デコードする方法について説明しています。
ここで、アプリのURIをエスケープする必要があるとしましょう。より具体的なユースケースです。そのため、RubyコミュニティURI.escape
は長年使用されていました。の問題URI.escape
は、RFC-3896仕様を処理できないことでした。
URI.escape 'http://google.com/foo?bar=at#anchor&title=My Blog & Your Blog'
# => "http://google.com/foo?bar=at%23anchor&title=My%20Blog%20&%20Your%20Blog"
URI.escape
廃止としてマークされました:
さらに、現在のURI.encodeは単純なgsubです。しかし、URIをコンポーネントに分割し、各コンポーネントをエスケープして、最後にそれらを結合する必要があると思います。
そのため、現在のURI.encodeは有害であると見なされ、非推奨になっています。これは削除されるか、動作が大幅に変更されます。
現時点での交換は何ですか?
上で述べたように、現在のURI.encodeは仕様レベルでは間違っています。そのため、正確な代替品は提供しません。交換は、そのユースケースによって異なります。
残念ながら、ドキュメントにはそれについて一言もありません。それを知る唯一の方法は、ソースを確認するか、詳細レベル(-wW2
)で警告付きでスクリプトを実行する(またはgoogle-fuを使用する)ことです。
いくつかは、提案を使用してCGI::Escape
、あなたが全体のURIを逃れることができなかったため、クエリパラメータのために:
CGI::escape 'http://google.com/foo?bar=at#anchor&title=My Blog & Your Blog'
# => "http%3A%2F%2Fgoogle.com%2Ffoo%3Fbar%3Dat%23anchor%26title%3DMy+Blog+%26+Your+Blog"
CGI::escape
クエリパラメータのみに使用する必要がありますが、結果は仕様に反します。実際、最も一般的な使用例は、application/x-www-form-urlencoded
POSTリクエストの送信中など、フォームデータのエスケープです。
また、WEBrick::HTTPUtils.escape
あまり改善されていません(gsub
これも単純な、つまりIMOであり、よりも悪いオプションですURI.escape
):
WEBrick::HTTPUtils.escape 'http://google.com/foo?bar=at#anchor&title=My Blog & Your Blog'
# => "http://google.com/foo?bar=at%23anchor&title=My%20Blog%20&%20Your%20Blog"
仕様に最も近いのは、アドレス指定可能な gemです。
require 'addressable/uri'
Addressable::URI.escape 'http://google.com/foo?bar=at#anchor&title=My Blog & Your Blog'
# => "http://google.com/foo?bar=at#anchor&title=My%20Blog%20&%20Your%20Blog"
以前のすべてのオプションとは異なり、Addressableはエスケープしないこと#
に注意してください。これは予想される動作です。#
ハッシュをURIパスに保持し、URIクエリには保持しない場合。
残っている唯一の問題は、クエリパラメータを適切にエスケープしなかったということです。これにより、URI全体に対して単一のメソッドを使用すべきではありません。これまでのところ、完全な解決策はないからです。あなたが見るよう&
に、「私のブログとあなたのブログ」から逃れられませんでした。クエリパラメータには異なる形式のエスケープを使用する必要があります。ユーザーはURLで特別な意味を持つさまざまな文字を使用できます。URLエンコードを入力します。URLエンコードは、「疑わしい」クエリ値ごとに使用する必要があります。ERB::Util.url_encode
。
ERB::Util.url_encode "My Blod & Your Blog"
# => "My%20Blod%20%26%20Your%20Blog""
すばらしいですが、Addressableは既に必要です。
uri = Addressable::URI.parse("http://www.go.com/foo")
# => #<Addressable::URI:0x186feb0 URI:http://www.go.com/foo>
uri.query_values = {title: "My Blog & Your Blog"}
uri.normalize.to_s
# => "http://www.go.com/foo?title=My%20Blog%20%26%20Your%20Blog"
結論:
URI.escape
または類似したものCGI::escape
フォームエスケープのみが必要な場合にますAddressable
gemの1つとして使用する余裕がある場合は、最初にURLを解析できます。firubydoc.info/gems/addressable/Addressable/URI.heuristic_parse
Addressable:URL
その後、そのインスタンスのすべてのメソッドを呼び出すことができます。おそらくそのうちの1つが目的の結果を得るでしょう:rubydoc.info/gems/addressable/Addressable/URI
URI.escapeは、安全でないものをマークできる2番目のパラメーターを受け取ります。APIDockを参照してください:
CGI::escape
テキストセグメントのエスケープに適しているため、URLクエリパラメータ( '?'の後の文字列)で使用できます。たとえば、URLにスラッシュ文字を含むパラメーターが必要な場合は、最初にその文字列をCGI :: escapeしてから、URLに挿入します。
ただし、Railsではおそらく直接使用することはないでしょう。通常、内部でhash.to_param
使用するを使用CGI::escape
します。
URI::escape
正しくエスケープされなかったURLをエスケープするのに適しています。たとえば、一部のWebサイトは、アンカータグに間違った/エスケープされていないURLを出力します。プログラムがこれらのURLを使用してより多くのリソースをフェッチする場合、OpenURIはURLが無効であると文句を言います。必要があるURI::escape
有効なURLにするためには、これらを使用するます。したがって、URIストリング全体をエスケープして適切にするために使用されます。私の言葉では、URI :: unescapeはURLを人間が読めるようにし、URI :: escapeはそれをブラウザに有効にします。
これらは私の素人の用語であり、自由に修正してください。
違いは、URI.escapeが機能しないことです...
CGI.escape"/en/test?asd=qwe"
=> "%2Fen%2Ftest%3Fasd%3Dqwe"
URI.escape"/en/test?asd=qwe"
=> "/en/test?asd=qwe"
CGI.escapeは、クエリ文字列のURL値をエスケープするためのものです。ALPHA、DIGIT、「_」、「-」、「。」に該当しないすべての文字。および ''文字セットはエスケープされます。
ただし、URLには「/」、「:」、「?」、「[」、「&」、「=」、および「;」が必要なため、URLは正しくありません。おそらく、頭のてっぺんからは考えられないことでしょう。
URI.escapeはこれらのURL文字をそのままにし、エスケープするクエリ文字列のキーと値を見つけようとします。ただし、値はすべての種類の文字を含むことができるため、簡単にエスケープできないため、これに依存することはできません。基本的に、手遅れです。ただし、URLが単純である(値に「&」や「=」などが含まれていない)と依存できる場合、この関数を使用して、読み取り不能または不正な文字をエスケープすることができます。
一般に、「&」で結合して「?」の後に追加する前に、常に個々のキーと値にCGI.escapeを使用します。
CGI.escapeはOpenProject APIでは機能しませんでした。+ではなく、[] 、:をエンコードしました。私はこれを一緒にハッキングしましたが、これは今のところOpenProjectのAPIで機能しているようです。しかし、いくつかの.gsubが欠落していると確信しています。URI.escapeとほぼ同じくらい悪い可能性がありますが、廃止されたエラーは表示されません。
class XXX
def self.encode(path)
path, query = path.split("?", 2)
return path if query.nil?
query = CGI.escape(query).gsub("%3A", ":").gsub("%3D","=").gsub("%5B","[").gsub("%5D","]").gsub("%2C",",").gsub("+","%20")
return [path,query].join("?")
end
end
XXX.encode("http://test.com/some/path?query=[box: \"cart\"]")
URI.encode("http://test.com/some/path?query=[box: \"cart\"]")
両方の出力:
=> " http://test.com/some/path?query=[box:%20%22cart%22] "
=> " http://test.com/some/path?query=[box:%20 %22cart%22] "