window.open()で新規開いた小窓ウィンドウで親ウィンドウのdocumentを取得するには
下記のプロパティを使います。
window.opener.document
これで親ウィンドウの値を取得するだけではなく、
値を編集することもできます。
例えば下記のコードは親ウィンドwのフォーム内のテキストをAAAに変更します。
新規開いたページに記述します。
window.opener.document.FORM1.TEXT1.value = "AAA";
window.open()で新規開いた小窓ウィンドウで親ウィンドウのdocumentを取得するには
下記のプロパティを使います。
window.opener.document
これで親ウィンドウの値を取得するだけではなく、
値を編集することもできます。
例えば下記のコードは親ウィンドwのフォーム内のテキストをAAAに変更します。
新規開いたページに記述します。
window.opener.document.FORM1.TEXT1.value = "AAA";
テキストボックスの文字を選択された状態にする方法とその解除方法です。
IEの場合selectボックスにselect()関数を使うとJavaScriptエラーになります。
Firefoxは大丈夫です。
function selectFocusText(element){
// for IE
if (element.nodeName == "SELECT") return;
element.select();
};
function unselectFocusText(){
// for IE
if (document.selection) {
document.selection.empty();
// for Firefox
} else if (window.getSelection) {
window.getSelection().removeAllRanges();
}
};
ここが危ない!Web2.0のセキュリティ:第1回 Ajaxとクロスサイトスクリプティング|gihyo.jp … 技術評論社の勉強メモ&実験です。
あるJavaScriptの拡張子をcsvに変更してSCRIPTタグでそれをインポートするHTMLを用意します。
そのJavaScriptを実行しようとするとIEのデフォルトセキュリティオプションでは、
ファイルのダウンロードダイアログが出ます。
Firefoxは拡張子がcsvにもかかわらずちゃんとJavaScriptと認識してそれを実行します。
CSVファイルは単にカンマで区切られたデータですので,スクリプトは実行されないはずです。
Internet Explorerの仕様にセキュリティ設定に「内容によってファイルを開く」という設定ががあります(図2)。
![]()
これは,Internet Explorerがファイルの中身を見て,その中にHTMLっぽい文字列が含まれていればHTMLだと判断するということを意味しています。このため拡張子やレスポンスに含まれるContent-Typeヘッダとは関係なく,外部から参照可能なファイルにはクロスサイトスクリプティング対策が必要であるということになります。
一方,Firefoxの場合はレスポンスのContent-Typeヘッダを見て判断しますので,ファイルの中身が何っぽいのかを気にする必要はありません。
この観点からはIEのほうがセキュリティの面で高いと見られます。
簡単に言うとJavaScriptをブックマークしたものです。
普通はURLをブックマークするに対し、JavaScriptをブックマークします。
そしてこのブックマークを選ぶときは保存されたJavaScriptが実行されます。
iPhoneのブラウザ関連のアプリでは結構使われています。
javascript:window.scrollTo(0,document.documentElement.scrollHeight);
参考サイト:
gihyoサイトの「ここが危ない!Web2.0のセキュリティ」連載の第2回:「Same-Originポリシーと迂回技術」の勉強メモです。
他のドメインのサイトへはリクエストを送信できない制限のことをSame-Originポリシーと呼びます。同じドメインであってもポート番号やプロトコル(HTTPとHTTPSなど)が異なれば,異なるサイト(クロスドメイン)とみなされアクセスできません。クロスドメインアクセスは機能として実装されていないのではなく,セキュリティ上の理由から禁止されているそうです。
![]()
俺があの黒の攻撃者とし、攻撃目標がユーザのメールアカウント情報だとします。もしクロスドメインにアクセスする制限がなければ、事前に用意したスクリプトで(urlをメールサーバに設定)メールアカウントの情報が取得できるようになってしまいます。(この辺りはCookieの話が出てきます)
Ajaxだけではなく、フレームやサブウインドウの情報にアクセスする場合などにも存在する
* リバースPorxy
* SCRIPTタグ(JSONP)
* Flash
* 画像
* スタイルシート
![]()
データ提供サーバにとってユーザの身元は隠れているため、攻撃者に利用しやすい
ユーザの身元を確認しようとすると、ユーザ情報を扱わなければならない
ユーザ情報–>サーバ–>データ提供サーバ
前回の記事の続きとしてJSONPを勉強しました。
XMLHttpRequestはセキュリティ上の制限により、
クロスドメインの通信ができないです。
でもウェブサービスのようなどうしてもクロスドメインで通信したい場合があります。
その時の手段してあげられるのがこのScriptタグです。
(他の手段としてiframeやflashとリバースプロキシがあるそうです)
これを一番分かりやすく説明してくれたのははてなキーワードだと思います。
JSON with paddingの略
Javascriptの非同期通信でよく使われるXMLHttpRequestオブジェクトにはSame-Originポリシーが存在し、クロスドメインアクセスができない。
一方,scriptタグを用いると,ドメインの異なるサーバに置いているスクリプトファイルを読み込むことができる。この仕組みを利用し、scriptタグのsrcに、データを取得できるAPIのURLを指定し,ドメインの異なるサーバからデータを取得する仕組みの総称として、JSOPという言葉が使われる。JSONP用のAPIでは、関数名+取得データをjson形式で表記して引数とした形式(例.callbackFunc({id:1000,name:aaa}))のレスポンスが一般的で、APIから返されるコールバック関数と同じ名前の関数(callbackFunc(jsonData))をクライアント側で定義しておけば、データを読み込んだ際にそのコールバック関数が実行される。動的にscriptのDOMを生成することで、非同期でデータが取得できるようになる。
ただし、Same-Originポリシーが存在しないため、機密情報をAPIに含める際には十分な注意が必要である。
やはりソースコードで読むほうが早いだと思います。
以下gihyo.netからのサンプルコードです。
<html> <body> <script> function callback(x){ // コールバック関数を定義 alert(x["name"]); } </script> <script src="http://mail.example.com/json.dat"></script> </body> </html>
json.datの中身
callback( { "name" : "Fukumori" } );
要はクライアント側で先にデータを扱うコールバック関数を定義
その名はデータの提供側とのコールバック関数名と一致する必要がある
scriptタグでデータ提供サーバのデータをインポート
すると先に用意したコールバック関数が走ってデータを処理する
もっと詳しい動作原理とセキュリティはgihyoの特集を参照してください。
とても分かりやすいです。おすすめ!
ここが危ない!Web2.0のセキュリティ:第3回 JSONPでのクロスドメインアクセス|gihyo.jp … 技術評論社
jQueryのAjaxメソッドには$.getJSONがあります。
このメソッドはjQuery1.2からJSONPも対応したようです。
As of jQuery 1.2, you can load JSON data located on another domain if you specify a JSONP callback.
利用方法はurlの最後に”?”付きのコールバックパラメータを追加することです。
例えば”example.com?callback=?”こんな感じです。
callbackの値は指定しなくてもよいみたい、
jQueryが自動で変換してくれます。
ただしコールバックのパラメータ名はデータ提供側によって異なるかもしれません。
例えばヤフーPipesは”_callback=?”を要求してるそうです。
iframeで動的に画面を読み込む際URL不正などによる通信エラーが起こした場合の
エラーハンドラを追加したかったので判断するロジックが必要でした。
わざと誤ったURLを渡して検証しましたが、以下のコードはだめでした。
// documentがnullかと思ってそれで判断しようとしたんです。 if (this.contentWindow.document) {}
あるプロパティは存在しているのに、アクセスができない。コードで書くと
// プロパティがオブジェクトに存在するかを判断 // ここはアラーとが出した、つまり存在したってこと if ("aProperty" in obj) alert('obj has aProperty'); // 次にそのオブジェクトにアクセスしようとすると // エラーになった obj.aProperty
IE8の開発ツールで見たら「アクセスが拒否されました」と書いてある。
判断のロジックをtry-catch文に書けばいいです。
try { this.contentWindow.document; } catch (e) { if (e.number == -2147024891) { //アクセスが拒否されました。 alert(e.message); } else { alert("別のメッセージ"); } }
argumentsは配列じゃないため、配列のメソッドは
使えません。ということは本を読んだとき当たり前だと思ったんですが、
実際コードに落としたときは
自然とargument.slice()を書いちゃいました。
Array.prototype.<配列のメソッド>.call(arguments,<パラメータ>)
Array.prototype.slice.call(arguments,2)
上記の意図としてはarguments.slice(2)の表現に近いです。
ここでちょっとargumentsの基本知識を復習します。
length属性もあるし、[]でindex指定のオブジェクトを参照できますけど、
argumentsは配列に似ているオブジェクトだけです。
Technically, argumentsは予約語ではないですが、
予約語として認識してよいです。
つまりargumentsという変数は作成しないでってことです。
function foo(x){ alert(x); var arguments; arguments[0] = null; //xの値が変更されちゃう alert(x); // null が出力される }
Refers to the function that is currently being executed.
今実行中のファクションを参照しています。
function(x) { if (x <= 1) return 1; return x * arguments.callee(x-1); }
// ブラウザがIEの場合 if (window.ActiveXObject) { try { //IEのXMLHttpRequestオブジェクトを試しに生成 var xhr = new ActiveXObject("Microsoft.XMLHTTP"); } catch (e) { alert('ActiveXコントロールは無効になっています'); } }
恥ずかしいことに今仕事でjQueryでばりばりAjaxを使ってますが、
実際はただjQueryの便利なAPIを使っただけで
Ajaxそのものの仕組みも分かっていません。
今更ですが、その辺の基礎知識を勉強しできるだけ誰にも分かるように
自分が理解したことをメモとして残したいです。
JavaScriptなどのウェブブラウザ搭載のスクリプト言語で、サーバとのHTTP通信を行うための組み込みオブジェクト(API)である。
すでに読み込んだページからさらにHTTPリクエストを発することができ、ページ遷移することなしにデータを送受信できるAjaxの基幹技術である。
なるほど、これがAjaxを支える基幹ですね。
JavaScriptのオブジェクトです。
名前にXMLがついていますが、XML以外のデータも扱うことができます。
XMLHttpRequestは、マイクロソフトがOutlook Web Access 2000のダイナミックHTMLによるウェブインターフェースに活用するため、1999年公開のInternet Explorer 5においてActiveXオブジェクトとして実装したのが始まりである[1]。その後、2001年にMozillaプロジェクトがこれと互換性のある組み込みオブジェクトをMozilla 0.9.7およびNetscape 7で実装し、アップルも2004年にSafari 1.2でMozillaと同様の組み込みオブジェクトを実装し始めた[2]。
このように徐々にInternet Explorer以外のブラウザにも実装されていったXMLHttpRequestは、2005年にAjaxによって一躍有名になった。
ようは各ブラウザが先にXMLHttpRequestオブジェクトを実装した、
そして偉い人がAjaxを提唱してから一気に有名になった訳ですよね。
AllAboutの記事に載ってた仕組みを自分で書きました。
XMLHttpRequestのメソッドやプロパティは多分これからも使うことはありませんが、
一応図で見て大体把握しておきましょう。
openメソッドはイニシャライズみたいな感じで、GETかPOSTか、URLなどのパラメータを受け取ります。
そしてsendメソッドによるサーバに送信する前に、onreadystatechangeイベントのコールバックでステータスを判断しresponseTextやresponseXML プロパティのデータを返す流れですね。
拡張機能から XMLHttpRequest を使いたい場合は、非同期でロードするようにすべきです。
非同期の使用法では、データを受け取ったときにコールバックを受け取ります。
そのため、リクエストが発生している間はブラウザは通常どおりに動き続けます。
ブラウザにより異なる。
IE では、ActiveXObject(“Microsoft.XMLHTTP”) を使用。
IE のバージョンによっては、ActiveXObject(“Msxml2.XMLHTTP.5.0″) , ActiveXObject(“Msxml2.XMLHTTP.4.0″) ,
ActiveXObject(“Msxml2.XMLHTTP.3.0″) , ActiveXObject(“Msxml2.XMLHTTP”) なども使用出来る。
Mozilla 系ブラウザでは、XMLHttpRequest() を使用。
var req;
if( window.XMLHttpRequest){
req = new XMLHttpRequest();
}else if(window.ActiveXObject){
try {
req = new ActiveXObject("MSXML2.XMLHTTP");
} catch (e) {
req = new ActiveXObject("Microsoft.XMLHTTP");
}
}
if (req) {
req.open('GET', 'http://www.example.com/contents.txt');
req.onreadystatechange = function() {
if (req.readyState == 4) {
document.write(req.responseText);
}
}
req.send(null);
}
req.statusはHTTPレスポンスコードで200はOK、404はよく見るNot Foundです。
とりあえず自分が気になった点を書きました。
肝心なところはonreadystatechangeでのコールバックだと思います。
XMLHttpRequestは同一ドメイン内に制限されていますね。
別のドメインとのやり取りはどう行うのかを次のテーマにします。
なんかJSONPとかクロスドメインなどのキーワードがよく見えますが、
その辺をはっきりしようと思います。