URLEncode の方法
URLEncode は2種類ある
ちょっと古い資料を見ると
System.Net.URLClient.TURI.URLEncode
を使うと出てたりします。
例えば、↓こんな感じです。
program Project1;
uses
System.Net.URLClient;
begin
Writeln(TURI.URLEncode('Hello, Delphi!'));
// 出力:Hello%2C%20Delphi%21
Readln;
end.
で、それに従って TURI.URLEncode を使うと
[dcc32 警告] Project1.dpr(7): W1000 シンボル 'URLEncode' を使用することは推奨されていません : 'Use TNetEncoding.URL.Encode'
と、警告が出ます。
警告は消した方がいいよなーということで、警告に従って TNetEncoding.URL.Encode を使うようにしてみます。
program Project1;
uses
System.NetEncoding;
begin
Writeln(TNetEncoding.URL.Encode('Hello, Delphi!'));
// 出力:Hello%2C+Delphi!
Readln;
end.
警告も出ませんし、上手くいったように見えますが…
出力結果が変わっています!
Hello%2C%20Delphi%21
Hello%2C+Delphi!
空白が「%20」ではなく「+」になっています。
ちなみに、Docwiki の System.NetEncoding.TURLEncoding の文章は完全に日本語がおかしく
TURLEncoding は、スペース(プラス記号 + として)と、次の予約された URL エンコード文字のみをサポートします: ;:&=+,/?%#[]。 TURLEncoding は、プラス記号(スペースとして)と、どんなパーセント エンコード文字(%2A や %41 など)のデコードもサポートします。
意味が通じません。
日本語に直すと「空白は + 記号になる。また、;:&=+,/?%#[] 文字もエンコードされる」と書いてあります。
しかし、空白を「+」とすると正しく動かない処理もあります。
できれば、空白を「%20」にするか「+」にするか選べるといいですよね。
本当は2種類どころか、もっとある
先ほどの、TNetEncoding.URL.Encode は TURLEncoding.DoEncode を呼び出しますが、そこでは決め打ちで空白は「+」に変換しています。
↓こうなっています。
else if Sp^ = ' ' then
begin
Rp^ := '+';
Inc(Rp)
end
では、どうすればいいかというと TURLEncoding.Encode の別バージョンを呼び出せばOKです。
program Project1;
uses
System.NetEncoding;
begin
Writeln(TNetEncoding.URL.Encode('Hello, Delphi!', [], []));
Readln;
end.
TNetEncoding.URL.Encode は overload されたメソッドがあり、上記のように引数を指定すると別バージョンの Encode メソッドが呼ばれます。
別バージョンの TURLEncoding.Encode は第2引数に追加で %xx に変更する文字、第3引数で TEncodeOption を指定できます。
なお、TEncodeOption は下記の様に定義されています。
TEncodeOption = (SpacesAsPlus, EncodePercent);
- SpacesAsPlus は、空白を「+」に変換します。
- EncodeParcent は、「%」自身も変換するかどうかを示します。
今回は、空白を %20 にするだけだったので、第2, 第3引数は何も無しです。
また、先ほど「正しく動かない処理もある」と書きました。
なので、処理ごとにメソッドが用意されてればいいなあと思いますよね。
TURLEncoding には、ちゃんと用途ごとのメソッドも用意されています。
それがこちら
function EncodePath(const APath: string; const ExtraUnsafeChars: TUnsafeChars = []): string;
function EncodeAuth(const Auth: string; const ExtraUnsafeChars: TUnsafeChars = []): string; inline;
function EncodeQuery(const AQuery: string; const ExtraUnsafeChars: TUnsafeChars = []): string; inline;
function EncodeForm(const Input: string; const ExtraUnsafeChars: TUnsafeChars = []): string; inline;
です。
名前から何使うか解ると思います(DocWiki にはドキュメントが存在しません…)
コレを使って、先ほどのコードは、こうも書けます。
program Project1;
uses
System.NetEncoding;
begin
Writeln(TNetEncoding.URL.EncodeQuery('Hello, Delphi!'));
Readln;
end.
まとめ
いついかなる時も TNetEncoding.URL.Encode は引数を指定するか、用途ごとの Encode メソッドを使うようにしよう!