2019-05-06
Ajaxアクセス時のクロスドメイン制約問題を回避する
クロスドメイン制約を回避する方法をご紹介します。
Ajax通信を用いてjsonやCSVファイルを取得する場合、そのページとは別のドメインから取得したいということがあると思います。
そこで問題になるのがクロスドメインによる制約です。クロスドメイン制約は、セキュリティの観点から、アクセスしているページのドメイン以外のドメインからはAjax通信をさせないという制約です。
クロスドメインによる制約
例えば、https://example.com/サイト上のファイルから、Ajaxを用いてhttps://source.com/data.jsonを読み込んでみましょう。
下記のようなエラーが開発ツールのコンソールに表示されてしまいます。CORSヘッダがセットされていないので、異なるドメインのデータは取得できない、という内容です。これに対していくつかの回避策があります
firefoxの場合
クロスオリジン要求をブロックしました: 同一生成元ポリシーにより、https://source.com/data.json にあるリモートリソースの読み込みは拒否されます (理由: CORS ヘッダー ‘Access-Control-Allow-Origin’ が足りない)。
回避策① Access-Control-Allow-Originを設定する
Access-Control-Allow-Originを設定するにはサーバーサイドでの設定が必要となります。.htaccessによる設定が許可されていない、PHPが使えない環境であれば使えません。読み込みたいファイルが置いてあるサーバーを自分で管理している場合は、問題ないと思います。楽天GOLDサーバで使いたかったのですが、この方法では不可でした。
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin: "*"
</IfModule>
<?php
header('Access-Control-Allow-Origin: *');
?>
特定のドメインのみ許可する場合は、*をURLに置き換えてください。
<IfModule mod_headers.c>
Header set Access-Control-Allow-Origin: "https://example.com"
</IfModule>
<?php
header('Access-Control-Allow-Origin: https://example.com');
?>
回避策② プログラムを経由させて取得する
管理者でなくてもクロスドメイン制約を回避できる唯一の方法です。
プログラムからAjax通信させることで、同一ドメインへアクセスすることになり、クロスドメイン制約を回避することができます。下記の例ではPHPを使用使用していますが、前提としてPHPが動く環境であることが必要です。
getcsv.php
<?php
echo file_get_contents($_GET['url']);
?>
$(function(){
$.ajax({
url:"getcsv.php?url=https://source.com/data.csv",
type:"GET",
dataType:"text",
timeout: 5000
})
.done((data) => {
//成功した場合の処理
console.log(data);
})
.fail((data) => {
//失敗した場合の処理
console.log(data.responseText); //レスポンス文字列を表示
})
.always((data) => {
//成功・失敗どちらでも行う処理
console.log(data);
});
});
まとめ
取得するファイルを設置しているサーバを自身で管理しているのであれば、回避策①がスマートだと思います。
サーバサイドプログラムが動作する環境であれば、回避策②が確実に仕組みをコントロールできる方法ではないでしょうか。