相対URLから絶対URLへの変換
なぜ必要か
Location ヘッダは絶対URLでなければならない。
何らかの外部リクエストをする時には絶対URLが必要。
自力での取り扱いでは何が問題となるか?
一度 Parse しなければ正しく変換できない。(単純な切り貼りでは上手く行かない)
国際化ドメイン名(IDN)の考慮が必要。
いきなりパーセントエンコーディング(%xx)をデコードしてはならない。
パーセントエンコーディングは URL の表記とぶつからないためなので、要素に分解してからのみデコードが可能。
分解した要素はパーセントエンコーディングを外した物でなければならない。
二重エンコーディングの防止
相対位置指定のための ".", ".." と過剰なパス区切り/を適切に除去する必要がある。
パス区切りがパーセントエンコーディングされているケースが考えられる。
スキームなしのものも相対URL。絶対URLではない。
つまり //example.com/ は相対URL。
先頭スラッシュはホストの直後を示す。 基準URLからではない。
つまり基準URLが http://example.com/foo なら / は http://example.com/ を指す。
基準URLにパラメーターが付いていてもそれで補完されるべきではない。
つまり基準URLが http://example.com/foo?q=a の時に、. はhttp://example.com/fooとなる。
絶対URLへの変換には、基準URL(ベースURL)と相対URLが必要になる。
基準URLは通常は自分自身のURLで、それを取得する必要がある。
URL と書くか URI と書くか、どちらがよいのか?
JavaScript
var baseUrl = document.baseURI; // client
https://developer.mozilla.org/en-US/docs/Web/API/Node/baseURI
var baseUrl = document.location.href // for IE11
var absUrl = (new URL(relUrl, baseUrl)).toString(); // .href の方がいいか?
https://developer.mozilla.org/ja/docs/Web/API/URL/URL
core-js に URL の polyfill があるので、Babel でトランスパイルすると使えるようになる。
参考 URL Polyfill for IE11 https://stackoverflow.com/questions/59071573/url-polyfill-for-ie11
C#
Uri uri = new Uri(relUrl, baseUrl);
string absUrl = uri.AbsoluteUri;
https://docs.microsoft.com/ja-jp/dotnet/api/system.uri?view=netcore-3.1
PHP
なぜか適切な関数が標準にない?
サードパーティーライブラリの GuzzleHttp を使う。
参考
【PHP】相対パスを絶対パス(URL)に変換する https://qiita.com/fallout/items/347c4b0c377e025198e6
2行で完了!PHPでHTMLに埋め込まれた相対パスを絶対パス(URL)に「一括変換」する https://qiita.com/kd9951/items/787f7a6de85e5917dbc3
https://stackoverflow.com/questions/4444475/transform-relative-path-into-absolute-url-using-php
テスト用の変換セットはどうなるべきか?
参考
絶対 URL と相対 URL、絶対パスと相対パス https://knooto.info/url-absolute-relative/
RFC 3986 - Uniform Resource Identifier (URI): Generic Syntax
Keyword
相対URI,絶対URI,URI,相対パス,絶対パス
関連
URLの解析