スポンサーサイト

一定期間更新がないため広告を表示しています

  • 2013.01.21 Monday
  • -
  • -
  • -
  • -
  • by スポンサードリンク

続 クロスドメインで使う XMLHttpRequest と CORS の話

続きです、サーセン。

XMLHttpRequest でクロスドメイン通信したい!という話

前回の話でちらっと出てきた XMLHttpRequest Level2 と 新しい話題 CORS (クロスオリジンリソースシェアリング)について
今回も話が長いので結論を先に書いておくと

何も解決していない。

困ったな。どこから書こうかな。ひとつづつ書いていくと

まず CORS (Cross-Origin Resource Sharing) について。

以下に W3C の勧告があります。

http://www.w3.org/TR/cors/

詳しい部分はそちらを見てもらうとして、簡単な内容はこんなもの。

サーバ側はレスポンスヘッダに "Access-Control-Allow-Origin" というヘッダを加える。このヘッダに許可するアクセス元を記述する。クライアント側が "Access-Control-Allow-Origin" の情報を参照して、受け取った情報(レスポンスボディ)が本当に受け取って(参照して)いいものかどうかを判断する。

勧告ページの情報量を見る限りそれだけではないはずですが、XMLHttpRequest でクロスドメインアクセスしたい!という話に限ればそれだけです、たぶん。

「実装はどうなの?」というと、レスポンスヘッダに "Access-Control-Allow-Origin" ヘッダを加えるだけです。加える方法はなんでもいいと思います。

.htaccess で付加するなら

Header append Access-Control-Allow-Origin: *


php スクリプト中で対応するなら

header('Access-Control-Allow-Origin: *');


* はすべてのオリジンからのアクセスを「許可する」です。オリジンというのは、プロトコル・ドメイン・ポートの3つを合わせた情報のようです。ドメインが一緒でもポートが代われば別オリジン(今までどおりの言葉を使えば別ドメイン)ということです。

特定のオリジンのみを許可するなら

Access-Control-Allow-Origin: http://www.otherdomain.com


ついでですが Firefox でローカルファイル(file://xxxx)のオリジンは null です。

Access-Control-Allow-Origin: null


と書けばローカルファイルからのアクセスのみ許可できます。ほとんど意味ないですが。

これで 許可されたオリジンから XMLHttpRequset Level 2 に対応しているブラウザであれば、XMLHttpRequest でクロスドメイン通信が可能になりました。

クライアント側(JavaScript側)には処理の追加はありません。

そんなわけで サービス(アクセス先アプリ)側が "Access-Control-Allow-Origin" ヘッダで許可してくれたら、XMLHttpRequest でクロスドメイン通信ができるという結果になりました。

いみねー・・・(#^ω^)

そういう調整ができる=自ドメインのサービスてことですよ、普通。そういうのができないからクライアント側でなんとかしたいってのに・・・「サーバ側で対応できます^^」とか話になってないよ。自ドメインならなにも考えなくても通信できるんですよ。

まぁ、自分(自社)で管理サイト間でのクロスドメインにはちょー使えそうですね。www.hoge.com と shop.hoge.com があって www から shop へアクセスして人気商品をピックアップ表示したいとか。そして、iframe を利用してクロスドメインを実現するって方法はこの仕組みがあればまったく必要がなさそう。iframe を使う方法は、自社管理サイトだけど、サーバが別の場所で管理されていてインターネットへ出なければアクセスできない状況でのクロスドメイン対策な気がするから。

しかしね・・・この仕組みってサーバ側がアクセスを拒否したいかどうかだよね・・・。サービスの不正利用を拒否する仕組みってことだよね?前回「無制限に通信したらセキュリティ的に問題がある。だから、XMLHttpRequest ではクロスドメインへのアクセスを禁じている」いう話に収めたんだけども、実際はクライアントの都合はどうでもよくてサーバ側の都合だったってことですか?クライアント側がそのヘッダを無視したら完全に意味なしだよね・・・。ほんとに拒否したかったら、そもそもそんなサービスを置かないか、サーバ設定もしくはルータ設定でアクセスを拒否るよね。というか、その仕組み、クライアント側のセキュリティ問題をガン無視だよね。通信したらやばい相手は「全開放」に決まってるじゃん・・・。許可してるから大丈夫、て理論はマイクロソフトだけにしといてよ。ガン無視でいいなら、最初からクロスドメインさせてよ・・・。

余談に近いですが、クロスドメイン通信しようとしたときの Firefox のエラーはこんなのです。

エラー: uncaught exception: [Exception... "Component returned failure code: 0x80004005 (NS_ERROR_FAILURE) [nsIXMLHttpRequest.send]" nsresult: "0x80004005 (NS_ERROR_FAILURE)" location: "JS frame :: ${URL} :: ${FUNCTION} :: line ${LINE}" data: no]


ネット上で調べた限りでは

Permission denied to call method XMLHttpRequest.open


というエラーが出て通信できないという情報が優勢でした。

エラー内容が違うんですよね。「コンポーネントが失敗を返した」と「"実行する"権限がない」。エラーの出所も違います。方や send メソッド、方や open メソッド。そんなもんなので「本当にクロスドメインが動かない理由なの?」と悩んでいたんですが、今回の CORS と XMLHttpRequest にたどり着いたおかげで理解できました。

ほぼ間違いなくクロスドメインが理由。

エラー内容が違うのは "Permission denied" というエラーが XMLHttpRequest Level 2 を実装前のものだから(推測ですがw)。実装前だから open で接続する前にクロスドメインを理由にアクセスを拒否っている。実装後は send でリクエストボディを送信する前に open でとってきたリクエストヘッダをチェックしてアクセス許可されてないからコンポーネント(XMLHttpRequset)が失敗と返している。よくよく見るとオブジェクトも違う。nsIXMLHttpRequest と XMLHttpRequest。Lv2 実装前と後で違うってことでいいでしょう。

あー、すっきりした。

したけど

何も解決していない・・・

JSONP はかなりのサービスが対応し始めているけど、CORS に関してはまだまだ。してくれてたらこんなことで悩んでないしね・・・。JSONP に対応してればいいじゃんと思うべき?

世界各国、多種多様なサービスに「Access-Control-Allow-Origin で全許可する設定もしくプログラム修正を行ってください」て言ってまわれって?

ないわw

Google API なんかには "Access-Control-Allow-Origin" ヘッダが付いてますね。Map API にはついてました。Place API にはついてませんでした。でも Map API Liblary としての Place にはついてそうです。ちょっと首をかしげてしまう。


ついでなので XMLHttpRequest Level 2 について

以下に W3C の勧告があります。

http://www.w3.org/TR/XMLHttpRequest2/

詳しい内容はわかりません。英語読めません。義務教育なんて飾りですよ、エラい人にはそれがわからんのですよ。

対応ブラウザは House Tect. XMLHttpRequest level2に対応しているブラウザまとめ によると

OK Win Firefox3.5.9
OK Win Safari5.0
OK Win Chrome 7.0
NG Win Opera10.10
OK Win IE8
NG Win IE7
NG Win IE6
OK Mac Firefox3.6.12
OK Mac Safari5.0
OK Mac Chrome 7.0
NG Mac Opera10.10

Firefox, Safari, Chrome は OK
Opera は NG
IE は対応してようがしてなかろうが(最近のバージョンでは警告がでるけど)クロスドメインしちゃう

ということで

まったく動作確認してないけど、これで大丈夫じゃないかな?たぶん。

var xhr = null;
if ( typeof XDomainRequest != "undefined" ){
// IE8
xhr = new XDomainRequest();
} else if ( typeof XMLHttpRequest != "undefined" ){
// firefox 他
xhr = new XMLHttpRequest();
} else if ( window.ActiveXObject ) {
// IE 7 以前
xhr = new ActiveXObject("Microsoft.XMLHTTP");
} else {
// 未対応ブラウザ
return;
}


IE8 で XMLHttpRequest Level 2 を使う場合は XDomainRequest オブジェクトになるみたい。

スポンサーサイト

  • 2013.01.21 Monday
  • -
  • 13:32
  • -
  • -
  • -
  • by スポンサードリンク

コメント
コメントする








   
この記事のトラックバックURL
トラックバック
IEで当サイトを見たらWebフォントがうまく読み込まれていません。 IETesterで各バージョンのIEで閲覧したところIE9以降で不具合が出ていました。 右クリックから要素の検査で調べてみると @font-face が cross-origin 要求に失敗しました。リソース アクセスが制限され
  • RougeBleu
  • 2014/07/31 5:52 PM

calendar

S M T W T F S
    123
45678910
11121314151617
18192021222324
252627282930 
<< June 2017 >>

最近の記事

記事(カテゴリ別)

リンク

recent comment

recent trackback

  • 続 クロスドメインで使う XMLHttpRequest と CORS の話
    RougeBleu (07/31)

ブログ内検索

others