Home JavaScript Greasemonkey PHP

Chrome 正式版 Greasemonkey でクロスドメイン POST をする方法2010-01-29


最近公開された、Google Chrome の Ver 4 では、正式に Greasemonkey がサポートされ、以前のように特別なオプションを指定することなく、ワンクリックでユーザスクリプトがインストール出来るようになりました。
それ自体は非常に嬉しい事だったんですが、バージョンアップに伴い、はてブ with Twitter が動かなくなってしまっていました。(現在は修正済み)

以前、JavaScript だけでクロスドメインで POST メソッドを送る方法で紹介したやり方が、Chrome のバージョンアップによって無効になってしまったためです。
無効になったとはいえ、通常の JavaScript として使用する分には問題なく、Greasemonkey だけに問題が発生していました。
動的に生成した iframe の contentWidow オブジェクトが取得出来なくなっており、セキュリティの制限が強化されたものと思われます。

最終的にはその制限を回避する方法を見つけたので、以下に解説します。

通常 JavaScript の記述

まず、Greasemonkey ではなく普通の JavaScript としてJavaScript だけでクロスドメインで POST メソッドを送る方法等を参考に、本来やりたい処理を記述します。
この時は普通に script タグでスクリプトを読み込んで、正常動作を確認しておきます。

そして、正常に動作するスクリプトが作成出来たら、それを任意のサーバにアップします。

Greasemonkey の記述

以下のようなスクリプトを書きます。
(function() {
    var d = document;
    var s = d.createElement('script');
    s.src = 'http://www ...'; // スクリプトファイルをアップした場所
    d.body.appendChild(s);
})();

これだけで、本来の window オブジェクトから実行したかった処理が実行され、Greasemonkey の制限に掛かることなく、iframe を使用したクロスドメイン POST が実現します。

でもちょっと待って

Greasemonkey が実行されるたびに、自分のサーバから js ファイルがダウンロードされるなんて嫌ですよね?私は嫌です。レスポンスを考えたって好ましくないですし。

そこで、data スキームを使って外部スクリプト自体を Greasemonkey スクリプトの中に埋め込んでしまう事にします。(data スキームについてはこの辺を参照して下さい。)

data スキームへの変換には、[JavaScript] dataスキームURI生成(画像データのBase64変換)を使用させていただきました。
このサイトで、先ほどアップした js ファイルの URL を指定し、data スキームに変換した文字列を取得します。

その上で、Greasemonkey を以下のように書き換えます。
(function() {
    var data = 'data:application/x-javascript;base64,'+
        'KGZ1bmN0aW9uKCkgewoJdmFyIGQgPSBkb2N1bWVudDsKCWZ1bmN0aW9uIGdldEVsZW1lbnQoeHBh'+
        // 中略
        'fSkoKTs=';
        var d = document;
    var s = d.createElement('script');
    s.src = data;
    d.body.appendChild(s);
})();

これで、単体の Greasemonkey スクリプトでありながら、外部スクリプトを読み込んだのと同等の状況を作り出す事が出来ます。

これでスッキリしましたね!