aboutme:139035
Google ChromeのUserScriptの制限がGreasemonkeyに比べて強いので、メインのスクリプトを(ローカルの)httpdからロードし、そのロードさせる部分のみUserScriptとして書くという方針にするとして、「環境変数」を渡すのをどうするか考えた。 (JRF 0297)
JRF 2011年5月31日 (火)
値の escape は encodeURIComponent を使えば良さそうだ。
コードとしては次みたいなの。
Array とかは面倒だから、あとから split するなりして作ればいいと思う。
JRF 2011年5月31日 7449
<pre>
function make_variable_injection(name, value) {
return "window['" + name + "'] = decodeURIComponent(\""
+ encodeURIComponent(value) + "\");";
}
var vscr = document.createElement('script');
vscr.textContent = make_variable_injection("VAR1", VAR1);
document.body.appendChild(vscr);
</pre>
JRF 2011年5月31日 4094
CSS とかについても似たようなことができる。ただし、head に書かないとダメなので、var head = document.getElementsByTagName('head')[0] に appendChild するのを忘れないこと。
JRF 2011年5月31日 1129
参考。
《Dynamically loading an external JavaScript or CSS file》
http://www.javascriptkit.com/javatutors/loadjavascriptcss.shtml
《Google Chromeでも動くユーザスクリプトを書くためのメモ - maru source》
http://d.hatena.ne.jp/h13i32maru/20100606/1275816792
JRF 2011年5月31日 3720
……。
あと、Chrome の制限として、E4X が使えないというのがあった。
そこは簡単に書き換えることができる……おおっ、それだけで Firefox 用に作った↓の statuses_editor の CGI 版が動いたぞ!
《aboutme2cocolog: アバウトミーの「ひとこと」をココログプロへ移転するツール》
http://jrf.cocolog-nifty.com/software/2011/04/post.html
さて、次は IE で動かせるか…だが…。
JRF 2011年6月1日 4261
……。
もひとつひっかかった。
UserScript で、window.addEventListener に load で登録しても、普通(Firefox)だったら Emacs の eval-after-load みたいに実行されるんだけど、Google Chrome はロードが終っていると判断しているらしく実行してくれない。document.loaded みたいなものが欲しいところだが、あまり適当なものがなさそうなので、↑で、スクリプトの中から実行していることを示すフラグを渡すことで、addEventListner するか直接実行するか、制御することにした。
JRF 2011年6月1日 3519
……。
ところで、IE は XDomainRequest が何かと面倒でまいった。何が面倒って、同期(sync)ができないのがメンドクサイ。あきらめて、コメント書き込みとかは諦めて、alias の反映とか最低限のとこだけやることでお茶をにごした。IE6 じゃあはなから反応ないし(GET で送ってもダメだった。)
それに XDomainRequest、setRequestHeader がないから、POST のとき Content-Type を application/x-www-form-urlencoded にすることができない。
JRF 2011年6月1日 2821
これを、Perl の CGI.pm でムリヤリにでも解釈させるには、結局、CGI->new する前に↓みたいに環境変数を書き換えるぐらいしか方法がなさそうだった。(CGI->new(join("", <STDIN>)) だけはダメだった。)
JRF 2011年6月1日 1903
<pre>
if (exists $ENV{REQUEST_METHOD} && $ENV{REQUEST_METHOD} eq "POST"
&& $ENV{HTTP_USER_AGENT} =~ /MSIE/) {
$ENV{'CONTENT_TYPE'} = 'application/x-www-form-urlencoded';
}
my $CGI = CGI->new;
</pre>
JRF 2011年6月1日 2007
……。
うわっ。やられた。Firefox 4.0 よりまえ 3.6 とか 3.5 とかだと、req.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); すると失敗する。
↓によると、4.0 から url-encoded で OK になったけどそれ以前は、text/plain じゃないと、'preflighted' と判断され、OPTIONS 要求に応えないとダメらしい。だから上の $ENV にムリヤリ値をセットするトリックは、MSIE 以外のFirefox/3 とか他のものに関してもやらないとダメ。
JRF 2011年6月5日 5221
《HTTP access control - MDC Docs》
https://developer.mozilla.org/en/http_access_control
一つ前のひとこと↓。
http://jrf.aboutme.jp/user_statuses/show/139032
>Firefox の XMLHttpRequest で CGI からエラーを返すと、Uncaught exception が起きる。onerror とかのハンドラを設定してもダメ。結局、try { } catch { } で囲んでやるほかなかった。<
JRF 2011年6月5日 3304
Ajax を使うときに Cookie でセッションID 渡すのはまだ実用的じゃないのかな?
JavaScript をロードするとき、セッションID をしこんでおいて Access-Control-Allow-Origin は使わないほうがいいのかな?でも、こういう機構が出てきてるってことは、それがいつまで認められるかわからないってことだろうし…。
JRF 2011年6月5日 0910
'preflighted' のほかに、IE には P3P ポリシーとかあるらしいけど、その辺もまだ私はわかってない。(ブラウザの違いが多すぎてやってらんない!orz)
《非同期クロスドメイン通信でCookieを送信したかった (それなりブログ)》
http://kjirou.sakura.ne.jp/mt/2011/03/cookie_1.html
JRF 2011年6月5日 6953
さらに、Google Chrome は req.setRequestHeader("Content-Type", "test/plain"); と明示的に設定しないと(setRequestHeader を削ってるのでは)ダメっぽい。
なんじゃそりゃーっ。これはかなり高い確率で罠だな。明らかに text/plain って MIME Type がおかしいもん。escape/unescape の二の舞になるだろうな…。まーた、わかっててこういうことをやらせるわけか。OPTIONS リクエストをこういうときは使えって示唆なんだろうが…。ほんと evil な人たち。(もちろん、オレも含め。)orz
JRF 2011年6月5日 9104
トラックバック
他サイトなどからこの記事に自薦された関連記事(トラックバック)の一覧です。
JavaScript の Canvas にもオリジン制限があることを知る。開発者向けにブラウザ起動時にそれを無視するオプションはあるようだが、サーバーオーナーやブロガーが回避する方法はなさそう。 続きを読む
受信: 2012-01-04 14:58:44 (JST)
load する javascript の variable のいくつかを予め set するというか inject したい。
unsafeWindow が使えないため、関数や変数を渡すのにちょっとしたテクニックがいる。
JavaScript ファイルをロードするのは、var s = document.createElement('script') して s.src にファイル名を代入し、document.body.appendChild(s) すればいい。
同じリクツで、変数を渡すには、s.src に代入する替わりに、s.textContent にスクリプトの文を書けばいいだろう。
JRF 2011年5月31日 2060