例えば bit.ly みたいなのを使うと、こんな短縮URLができます。
1 |
https://bit.ly/xxxxxx |
こういう短縮URLのリダイレクト先(つまり元のページ)を知りたい・・・けどどういう調べ方があるのか分からなくてお手上げ状態
みたいに困ってたんですが、ついに調べ方が分かりました。
そこで同じように悩む人を減らすために、
ここでは PHP ・JavaScript でのリダイレクト先の調べ方 をまとめてみます。
1.PHPでリダイレクト先を調べる方法
PHPの場合、調べるのはそんな難しくないです。
一番手軽のは curl のヘッダー情報をみること
たとえば次に紹介するやり方で意外と簡単に取得できます。
例えば次はこのブログのトップの短縮URL
1 |
https://bit.ly/2Pa4lDz |
この展開先を調べる関数例は次の通りです。
▼こんな関数を作ってみた
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
define( 'MAX_URL_REDIRS', 20 ); function expand_url( $url, $redirs = 0 ) { if ( $redirs == MAX_URL_REDIRS ) { throw new Exception('TOO MANY REDIRECTS!!'); } $ch = curl_init( $url ); curl_setopt_array( $ch, [ CURLOPT_HEADER => 1, CURLOPT_NOBODY => 1, CURLOPT_RETURNTRANSFER => 1, CURLOPT_SSL_VERIFYPEER => 0 ] ); $resp = curl_exec( $ch ); if ( preg_match( '/Location: (.*)/i', $resp, $matches ) ) { return expand_url( $matches[1], ++$redirs ); } return trim( $url ); } |
そのまんま expand_url っていう捻りのない関数名
この関数で大事なポイントは次の3つです。
- Curlのヘッダー情報から調べてる
まず普通に Curl を実行し、そのヘッダーに Location: が含まれてれば再帰的に関数を呼び出す。最後にリダイレクトが発生してないのが元のURL(である確率が高い)
- 最大の再帰回数を決めておく
このコードだと MAX_URL_REDIRS を20回に制限している。そうしないと無限に再帰関数が呼ばれることもあるので要注意
- ヘッダー部分だけを受け取る
Curlを実行する時にオプションに CURLOPT_NOBODY を指定している。こうすればムダなデータを受け取らないので高速化可能
再帰を使わない方法もあるかもしれないけど、面倒なので再帰してます。
リダイレクト先を調べるときは、こういうコードを書くだけです。
▼例えば bitly の元URLを調べるコード例
1 2 |
$url = 'https://bit.ly/2Pa4lDz'; echo 'dest url : '.expand_url( $url ); |
▼ このコードの出力結果
1 |
dest url : https://pisuke-code.com |
まあ短縮URLの元URLが分かって何になるのかって話だけど・・・
でもURLをフォームから受け取ったりするとき、短縮URLに変なドメインが混じってないか簡易的にチェックするときなどは役立つかもしれません。
あと純粋にURLのリダイレクト先を知りたいときも便利ですね。
2.JavaScriptでリダイレクト先を調べるには...
次はJavaScriptでリダイレクト先を調べる方法について
これははっきりと言います。
そんな方法ありません(たぶん)
実際いろいろ探し回ったけど、どうやら技術的に無理があるみたいです。
ただし!
さっき紹介したPHPでリダイレクト先を調べるスクリプト
アレを使えば、Ajax経由などでURLのリダイレクト先は分かります。
例えばPHP側でこういうスクリプトを用意しときます。
▼ PHP側のスクリプト例(レスポンス返す)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
/// 展開したいURLをPOSTから受け取る $url = $_POST['url']; /// URL展開してレスポンスで返す $expanded_url = expand_url( $url ); echo json_encode( $expanded_url ); /// URLを展開する関数 define( 'MAX_URL_REDIRS', 20 ); function expand_url( $url, $redirs = 0 ) { if ( $redirs == MAX_URL_REDIRS ) { throw new Exception('TOO MANY REDIRECTS!!'); } $ch = curl_init( $url ); curl_setopt_array( $ch, [ CURLOPT_HEADER => 1, CURLOPT_NOBODY => 1, CURLOPT_RETURNTRANSFER => 1, CURLOPT_SSL_VERIFYPEER => 0 ] ); $resp = curl_exec( $ch ); if ( preg_match( '/Location: (.*)/i', $resp, $matches ) ) { return expand_url( $matches[1], ++$redirs ); } return trim( $url ); } |
さっきのスクリプトを少し改造しただけ
▼ このPHPをAjax側から呼ぶ(レスポンス受け取り)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
/// リダイレクト先を知りたいURL var url = 'https://bit.ly/2Pa4lDz'; /// PHP側からURLの展開先を教えてもらう $.ajax({ url: '/path/to/expand-url.php', type: 'POST', dataType: 'json', data: { url: url } }).done(function(resp){ var expandedUrl = ''; try{ expandedUrl = JSON.parse(resp); }catch(e){ /// エラー処理 } console.log('リダイレクト先 : ', expandedUrl); }).fail(function(){ console.log('サーバー接続に失敗しました'); }); |
ちなみに想像で書いたので、もしかしたら少し間違いがあるかも
でもこれでJavaScript側からリダイレクト先が取得できます。
ただAjax単体では無理ので、こういう一工夫が必要なのが難しいところですね。
ここまでのまとめ
短縮URLとかの元URLを調べたいなら、PHPからCurlを呼び出すのが一番確実
もちろんCurlが使えるなら、他言語でもおんなじことはできると思います。
以上、PHP・JavaScriptでリダイレクト先を調べるやり方でした。