組み込みの URL クラスは、URLを作成および解析するための便利なインターフェースを提供します。
厳密にURL
オブジェクトを必要とするネットワークメソッドはありません。文字列で十分です。そのため、技術的にはURL
を使用する必要はありません。しかし、時にそれは非常に役立ちます。
URLの作成
新しいURL
オブジェクトを作成する構文
new URL(url, [base])
url
– フルURLまたはパスのみ (ベースが設定されている場合、下記参照)、base
– オプションのベースURL: 設定され、url
引数がパスのみを持つ場合、URLはbase
に対する相対で生成されます。
例:
let url = new URL('https://javascriptinfo.dokyumento.jp/profile/admin');
これら2つのURLは同じです
let url1 = new URL('https://javascriptinfo.dokyumento.jp/profile/admin');
let url2 = new URL('/profile/admin', 'https://javascriptinfo.dokyumento.jp');
alert(url1); // https://javascriptinfo.dokyumento.jp/profile/admin
alert(url2); // https://javascriptinfo.dokyumento.jp/profile/admin
既存のURLに対する相対パスに基づいて、新しいURLを簡単に作成できます。
let url = new URL('https://javascriptinfo.dokyumento.jp/profile/admin');
let newUrl = new URL('tester', url);
alert(newUrl); // https://javascriptinfo.dokyumento.jp/profile/tester
URL
オブジェクトを使用すると、すぐにその構成要素にアクセスできるため、URLを解析するのに最適な方法です。例:
let url = new URL('https://javascriptinfo.dokyumento.jp/url');
alert(url.protocol); // https:
alert(url.host); // javascript.info
alert(url.pathname); // /url
以下はURL構成要素のチートシートです
href
はフルURLで、url.toString()
と同じですprotocol
はコロン文字:
で終わりますsearch
– パラメータの文字列で、疑問符?
から始まりますhash
はハッシュ文字#
から始まります- HTTP認証がある場合は、
user
プロパティとpassword
プロパティも存在する可能性があります:http://login:password@site.com
(上記には描画されていません、めったに使用されません)。
URL
オブジェクトをネットワーク(およびほとんどの他の)メソッドに渡すことができますfetch
やXMLHttpRequest
でURL
オブジェクトを使用できます。URL文字列が期待されるほぼすべての場所で使えます。
一般的に、ほとんどのメソッドが文字列変換を実行し、URL
オブジェクトをフルURLを持つ文字列に変換するため、URL
オブジェクトは文字列の代わりに任意のメソッドに渡すことができます。
SearchParams “?…”
例えば、https://google.com/search?query=JavaScript
のように、特定の検索パラメータを持つURLを作成したいとしましょう。
URL文字列でそれらを提供できます。
new URL('https://google.com/search?query=JavaScript')
…しかし、スペースやラテン文字以外の文字などを含む場合、パラメータはエンコードする必要があります(詳細については下記を参照)。
そのため、URLプロパティ: url.searchParams
, URLSearchParams 型のオブジェクトがあります。
これは検索パラメータのための便利なメソッドを提供します
append(name, value)
–name
でパラメータを追加,delete(name)
–name
でパラメータを削除,get(name)
–name
でパラメータを取得,getAll(name)
– 同じname
を持つすべてのパラメータを取得 (例えば、?user=John&user=Pete
のようなことも可能です),has(name)
–name
でパラメータの存在を確認,set(name, value)
– パラメータを設定/置換,sort()
– 名前でパラメータをソート。めったに必要とされない,- …そして、それは
Map
と同様に反復可能でもあります。
スペースと句読点を含むパラメータの例
let url = new URL('https://google.com/search');
url.searchParams.set('q', 'test me!'); // added parameter with a space and !
alert(url); // https://google.com/search?q=test+me%21
url.searchParams.set('tbs', 'qdr:y'); // added parameter with a colon :
// parameters are automatically encoded
alert(url); // https://google.com/search?q=test+me%21&tbs=qdr%3Ay
// iterate over search parameters (decoded)
for(let [name, value] of url.searchParams) {
alert(`${name}=${value}`); // q=test me!, then tbs=qdr:y
}
エンコード
URLで使用が許可されている文字とそうでない文字を定義する標準のRFC3986があります。
許可されていない文字は、エンコードする必要があります。たとえば、ラテン文字以外の文字やスペースは、UTF-8コードに置き換えられ、%
がプレフィックスとして付加されます。例えば、%20
(スペースは、歴史的な理由から+
でエンコードできますが、例外です)。
朗報は、URL
オブジェクトがすべてを自動的に処理してくれることです。エンコードされていないすべてのパラメータを提供し、URL
を文字列に変換するだけです。
// using some cyrillic characters for this example
let url = new URL('https://ru.wikipedia.org/wiki/Тест');
url.searchParams.set('key', 'ъ');
alert(url); //https://ru.wikipedia.org/wiki/%D0%A2%D0%B5%D1%81%D1%82?key=%D1%8A
ご覧のとおり、URLパス内のТест
とパラメータ内のъ
の両方がエンコードされています。
各キリル文字はUTF-8で2バイトで表現されるため、2つの%..
エンティティがあり、URLが長くなりました。
文字列のエンコード
昔、URL
オブジェクトが登場する前は、URLに文字列が使われていました。
現在、URL
オブジェクトの方が便利なことが多いですが、文字列も引き続き使用できます。多くの場合、文字列を使用することでコードが短くなります。
ただし、文字列を使用する場合は、特殊文字を手動でエンコード/デコードする必要があります。
それのための組み込み関数があります
- encodeURI – URL全体をエンコードします。
- decodeURI – それをデコードして戻します。
- encodeURIComponent – 検索パラメータやハッシュ、パス名などのURLコンポーネントをエンコードします。
- decodeURIComponent – それをデコードして戻します。
自然な疑問は、「encodeURIComponent
とencodeURI
の違いは何ですか?どちらをいつ使用する必要がありますか?」ということです。
上の図でコンポーネントに分割されているURLを見ると、簡単に理解できます
https://site.com:8080/path/page?p1=v1&p2=v2#hash
ご覧のとおり、:
、?
、=
、&
、#
などの文字はURLで許可されています。
…一方で、検索パラメータなどの単一のURLコンポーネントを見ると、これらの文字はフォーマットを壊さないようにエンコードする必要があります。
encodeURI
はURLで完全に禁止されている文字のみをエンコードします。encodeURIComponent
は、同じ文字をエンコードし、それに加えて、#
,$
,&
,+
,,
,/
,:
,;
,=
,?
および@
の文字をエンコードします。
したがって、URL全体にはencodeURI
を使用できます
// using cyrillic characters in url path
let url = encodeURI('http://site.com/привет');
alert(url); // http://site.com/%D0%BF%D1%80%D0%B8%D0%B2%D0%B5%D1%82
…一方、URLパラメータには代わりにencodeURIComponent
を使用する必要があります
let music = encodeURIComponent('Rock&Roll');
let url = `https://google.com/search?q=${music}`;
alert(url); // https://google.com/search?q=Rock%26Roll
encodeURI
と比較してください
let music = encodeURI('Rock&Roll');
let url = `https://google.com/search?q=${music}`;
alert(url); // https://google.com/search?q=Rock&Roll
ご覧のとおり、encodeURI
は&
をエンコードしません。これはURL全体としては正当な文字だからです。
ただし、検索パラメータ内で&
をエンコードする必要があります。そうしないと、q=Rock&Roll
が得られます。これは実際にはq=Rock
と、いくつかの不明瞭なパラメータRoll
です。意図したとおりではありません。
したがって、URL文字列に正しく挿入するには、各検索パラメータにencodeURIComponent
のみを使用する必要があります。名前と値の両方をエンコードするのが最も安全です。許可された文字のみが含まれていると確信している場合を除きます。
URL
と比較したエンコードの違いクラスURLとURLSearchParamsは最新のURI仕様に基づいています: RFC3986。一方、encode*
関数は廃止されたバージョンRFC2396に基づいています。
いくつかの違いがあります。例えば、IPv6アドレスは異なる方法でエンコードされます
// valid url with IPv6 address
let url = 'http://[2607:f8b0:4005:802::1007]/';
alert(encodeURI(url)); // http://%5B2607:f8b0:4005:802::1007%5D/
alert(new URL(url)); // http://[2607:f8b0:4005:802::1007]/
ご覧のとおり、encodeURI
は角括弧[...]
を置き換えましたが、これは正しくありません。理由は、IPv6 urlがRFC2396(1998年8月)の時点では存在しなかったからです。
このようなケースはまれで、encode*
関数はほとんどの場合、正常に動作します。
コメント
<code>
タグを使用し、複数行の場合は<pre>
タグで囲みます。10行を超える場合は、サンドボックス(plnkr、jsbin、codepen…)を使用してください