やりたかったこと
AjaxでCross-Originが許可されていないサイトに対してアクセスして結果を取得したかった。
ここで、APIが返す結果は普通にブラウザで開いて見たような見た目にする必要があったのでリンク切れを起こさせたく無かった。
やったこと
最近はAjaxでAPI用に作られていないサイトにアクセスしてもCORSエラーが出て取得できません。
そのため、自分のサーバー側でcurlを実行し、その結果を返すAPIをAjax用に作成し、
Ajaxで作成したAPIにアクセスすることでSame-OriginなのでCORSエラーは出ず取得したかったものが取得できました。
作成したAPIではリンクを切らしたくなかったので出力されるものにbaseタグ
を追加しました。
<base href="http://example.com/test/"/>
とするだけで
このページ内の相対パスとルートパスを問題なく認識してくれる様です。
../css/test.css
は
http://example.com/css/test.css
/js/test.js
は
http://example.com/js/test.js
で認識してくれる。
なのでパスの置き換えなしに簡単に他のサイトの見た目を再現できる!
これは便利!
以下のようにcurlで取得してきたものをhead内にbaseタグを追加してやるだけです。
$ch = curl_init($url);// urlは対象のページ
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);// exec時に出力させない
$html = curl_exec($ch);
$base_url = (preg_match('/\/$/u', $url) === 1) ? $url : pathinfo($url)['dirname'];
// パスのリンクが切れるのでheadの直後に挿入
echo preg_replace('/<head>/u', '<head><base href="'.$base_url.'"/>', $html);
curl_close($ch);
結果
まだローカル環境で作業して確認しただけですが。
-
CORS回避もできた。
-
iframeで読み込みできないようにするX-Frame-Optionsも回避できた。
-
Ajax用に作成したAPIを直接画面にhtmlとして出力したら対象としたページの見た目と同じ画面が表示できた。
(出来ないサイトもあるかもしれませんが、実装しないで手っ取り早く確認したい場合は対象のページのソースコードをhtmlファイルに保存してbaseタグ
を入れると同じ見た目のページが確認できるかと思います。)