proxyサーバを通したときだけ、クロスドメインのajax呼び出しに失敗する原因

前回の記事で、クロスドメイン環境でajaxを呼び出すためには、ヘッダー「Access-Control-Allow-Origin」として「*」など、呼び出しを許可するドメインを指定すると書きました。

これはこれで有効なのですが、元々の目的である「無料ブログの記事から、自分が作ったWebサービスを呼び出す」ということを実現する場合には、対応できないケースがあることが、テストを行っていて、分かりました。

というのも、自宅で試した限りではうまく行くのですが、外部(自宅以外の環境)から記事を表示した場合は、うまく取得できる時と、取得できない時があります。

環境の違いを見てみると、インターネットのアクセスにproxyサーバを利用している環境では、呼び出しに失敗していました。

Fiddler2で呼び出しのシーケンスをキャプチャしてみると、原因が分かりました。

ログ↓

Refused to get unsafe header "X-JSON"
OPTIONS http://xxxx.com/servlet/search?sid=y&page=1&sort=0&kw=a
403 (Forbidden) prototype.js:1222
XMLHttpRequest cannot load
http://xxxx.com/servlet/search?sid=y&page=1&sort=0&kw=a
Origin http://mongas.blog.fc2.com is not allowed by
Access-Control-Allow-Origin.

ajaxでの呼び出しの際には、実際のGETでのコンテンツ取得の前に、一度、HTTPメソッドOPTIONSでサーバに問い合わせ、クロスドメイン通信が許可されているかを確認してからGETメソッド等で実際の通信を行なっているようです。

そして、このOPTIONSの応答が、proxyサーバを通した場合にはHTTPステータス「403 (Forbidden)」で返ってきていました。

で、なんでか?ということなのですが、これは、proxy側の設定によるようです。

つまり、proxyサーバで、OPTIONSなど、特定のHTTPメソッドを禁止していると、このような振る舞いになってしまします。

セキュリティ上の理由から、Httpサーバがサポートしているメソッドを判断するOPTIONSは禁止されていることが多いようですね。

もちろんこればセキュリティポリシー如何なので、proxyを通すと全てのクロスドメインの呼び出しができないわけではないです。

ただ、企業や学校内からのアクセスは、通常、プロキシを通すことが多いため、この人たちにはWebサービスの呼び出し結果が見えないというのはさびしい。。。

ということで、別の方法をとることにしました。

「JSONP」を使った方法で、クロスドメインでの呼び出しを行う方法です。

結果、プロキシを通しても呼び出しがうまく行きました。

この方法の詳細については、別の記事で解説したいと思います。