Last-modified: Tue, 03 Jul 2012 01:19:51 JST
クロスドメインでajax
仕事のITインフラ整備でひとつ解決したのでメモ。
クロスドメインのajaxで、セキュリティを乗り越えるために、最初は送信ヘッダに「Access-Control-Allow-Origin:*」と書いてたんだけど、IEを使いたいという困った人が現れて、ラッパースクリプトを書いて使っていた。
その後、Webサーバーへのリクエスト回数を減らすために、クエリをまとめて送受信するようにスクリプトを改変していたところ、クエリストリングが長くなり、「Query string too long」と怒られて失敗するようになってしまった。ラッパースクリプトへの通信をPOSTにするだけでは解決に至らない。
結局、ラッパースクリプト内のreadfile()の通信方法がデフォルトでGETになっていることが判明し、POSTに変更して無事成功。
解決までの経緯を記録しておくと、
- まずは上記のようにヘッダを送信。→ IEでNG
- このページ
を参考に、下記ラッパースクリプトを呼び出して転送。 → クエリが長いとNG
<?php
$url = $_GET['request'];
if(!$url) $url = $_POST['request'];
if(!$url) exit; //abandan...
header("Content-type: application/xml; charset=UTF-8");
readfile($url);
?>
ちなみに、上コードはセキュリティとか考えてない。$urlに悪意な文字列を入れるとヤバイ挙動になりそうな予感。
- このページ
を参考に、HTTPコンテキストオプションなるものを使用して、readfile()のデータ取得方法をGET(デフォルト)からPOSTに変更させた、下記スクリプトを使用することで解決。
<?php
$url = $_GET['request'];
if(!$url) $url = $_POST['request'];
if(!$url) exit; //abandan...
//POSTに変更
list($url, $query) = explode('?', $url);
$opts = array(
'http' => array (
'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded',
'content' => $query
)
);
header("Content-type: application/xml; charset=UTF-8");
readfile($url, false, stream_context_create($opts));
?>
これだとreadfile()がHTTPに限定されるみたいなので、セキュリティ的には何でも受け付けるよりマシなのかも。
ところで、今はjQueryのプラグイン使うとIEでもOKなの?