XMLHttpRequestを使っていたらCORSエラー?がでた

こんばんは。きわさです。

最近XMLHttpRequestを使っているとCORSという言葉に出会いました。
少し調べたのでメモ。

CORS

CORSとは、Cross-Origin Resource Sharingの略で、異なるドメイン間でリソースへのアクセスを許可することのようです。

何ができるかというと、例えば、http://test01.comにtest.phpがあるとします。
以下のようにGETをしようとした場合、同じhttp://test01.comからであれば取得できますが、
http://test02.comなど、異なるドメインから取得しようとした場合は失敗します。

var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://test01.com/test.php', true);
xhr.onreadystatechange = function() {
    if(xhr.readyState == 4) {
        var response = xhr.responseText;
    }
};
xhr.send(null);

こういった、http://test01.comhttp://test02.comのような異なるドメイン間で使用できるようにする仕組みのようです。

Preflight

異なるドメイン間でリクエストを送信する前に、送ろうとしているメソッドやヘッダをサーバーがサポートしているかを確認するためにPreflightが行われることがあります。
主に、GETやPOST以外のメソッドを使う場合や、リクエストヘッダを追加した場合などです。
これはOPTIONSメソッドを使って送信されます。
例えば下記のように、X-Testというヘッダを追加して送信をしてみます。

var xhr = new XMLHttpRequest();
xhr.open('GET', 'http://test01.com/test.php', true);
xhr.onreadystatechange = function() {
    if(xhr.readyState == 4) {
        var response = xhr.responseText;
    }
};
xhr.setRequestHeader('X-Test', 'Test');
xhr.send(null);

すると、OPTIONSメソッドでリクエストが送信され、また以下のようなヘッダが追加されています。

Origin: http://test02.com
Access-Control-Request-Method: GET
Access-Control-Request-Headers: X-Test

Originには送信元のドメインが、
Access-Control-Request-Methodには本来送信するメソッド、今回はGETが、Access-Control-Request-Headersには追加したヘッダX-Testが、ブラウザによって自動的に設定されています。

そして、サーバー側はサポートしている場合は以下のようなレスポンスを返す必要があります。

Access-Control-Allow-Origin: http://test02.com
Access-Control-Allow-Method: GET
Access-Control-Allow-Headers: X-Test

これは、http://test02.comからのX-Testが付加されたGETメソッドのリクエストを許可することを意味します。
ブラウザは、許可された場合のみ本来のリクエストを送信し、許可されない場合はリクエストを送信しないようです。

なるほど、こんな仕組みがあるんですね。勉強になります。

スポンサーリンク