XMLHttpRequest とは
そもそも XMLHttpRequest とはなんでしょう。
だらだらと書くと、XMLHttpRequest とは、javascript から HTTP アクセスを行う際に使用される API です。ブラウザから直接 HTTP アクセスする方式に比べ、Ajax 等の技術を使用すれば、Google Map のように画面遷移を行わなくとも情報を更新したりすることができます。但し、基本的にクロスドメイン(プロトコルやアドレスやポートが異なる)環境では情報の取得を行うことはできません。
XMLHttpRequest と難解な名称がついていますが、基本は HTTP です。また XML 以外のデータ(JSONなど)を扱うことも可能です。
実際のデータのやりとり
それでは実際に、サーバデータ(今回は JSON)にアクセスした場合、直接ブラウザでアクセスした場合と、XMLHttpRequest からアクセスした場合の HTTP ヘッダの違いを表示します。まずクロスドメインの場合です。
直接アクセスした場合
Request URL: Request Method:GET Status Code:200 OK
取得した JSON データは下記のようになります。
{
pinpointLocations:[
...
title: "石川県 金沢 の天気", description:{}
text: "(気圧配置など) 本州付近は高気圧に覆われています。 (天気分布など) 石川県は、晴れとなっています。 (今日の天気 24日) 高気圧に覆われますが、気圧の谷の影響を受けるでしょう。 このため、 石川県では、晴れで夜は曇りとなるでしょう。 (明日の天気 25日) 気圧の谷が通過する見込みです。 このため、 石川県では、曇りで朝から昼前にかけて雨となるでしょう。", publicTime: "2014-02-24T10:41:00+0900"}
次に、XMLHttpRequest からアクセスします
エラーとなります。エラー内容は、
XMLHttpRequest cannot load http://weather.livedoor.com/forecast/webservice/json/v1?city=170010. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost' is therefore not allowed access.
要するに、相手サーバ側が「Access-Control-Allow-Origin」ヘッダを出力していないため、XMLHttpRequest は、送信されてきたデータにアクセスしない。ということです。前にも記載しましたが、この場合でも JSON データは送信されてきています。あくまで XMLHttpRequest 側で拒否しているということです。
サーバ側に、「Access-Control-Allow-Origin」ヘッダの付与をお願いするわけにはいきませんし、これで手詰まりです。これを回避するには、javascript 以外の言語を使用するのみです。
では、同一ドメインではどのような情報がやりとりされているのでしょうか。
ブラウザから直接アクセスした場合
こちらは、クロスドメインと同様です。単に、HTTP/GET メソッドでデータを取得するだけですので、そのまま JSON データを受信します。
XMLHttpRequest からアクセスした場合
こちらも JSON データが正常に取得されます(データは割愛)。
「X-Requested-With」ヘッダが付加されています。これは、XMLHttpRequest が、自分が「XMLHTTPRequest」であることを宣言しているわけです。これにより、サーバ側はクライアントが XMLHttpRequest からアクセスされたことを認識できるわけです。ただ、これも繰り返しになりますが、ヘッダ情報はスクリプトなどを使用して疑似ブラウザを作成すれば、いくらでも改編できますので、それを完全に信用するのはセキュリティホールにつながります。
また、このヘッダ情報はクロスドメインでは送信されません。おそらく、もともとクロスドメインで XMLHttpRequest アクセスが許可されていないためであると思われます。