Kinopyo Blog

プログラマとしてRuby, Rails, iPhone, iPad,Macなどなどと向き合う日々のログポース

Archive for the ‘JavaScript’ Category

Javascript window.openで開いたページで親ウィンドウのdocumentを取得には

2010年01月29日

window.open()で新規開いた小窓ウィンドウで親ウィンドウのdocumentを取得するには

下記のプロパティを使います。

window.opener.document

これで親ウィンドウの値を取得するだけではなく、

値を編集することもできます。


例えば下記のコードは親ウィンドwのフォーム内のテキストをAAAに変更します。

新規開いたページに記述します。

window.opener.document.FORM1.TEXT1.value = "AAA";

参考サイト

とほほのJavascriptレファレンス:ウィンドウオブジェクト

テキストボックスの文字列を選択(色逆転)、取り消すには

2009年12月10日

テキストボックスの文字を選択された状態にする方法とその解除方法です。

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();

	}

};

拡張子が変更されたJavaScriptは実行されるか?IE,Firefoxでのセキュリティ

2009年12月02日

ここが危ない!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ヘッダを見て判断しますので,ファイルの中身が何っぽいのかを気にする必要はありません。

http://gihyo.jp/dev/serial/01/web20sec/0001?page=2

この観点からはIEのほうがセキュリティの面で高いと見られます。

iPhoneでページ最下部へ移動するブックマークレット

2009年11月27日

ブックマークレット(Bookmarklet)とは

簡単に言うとJavaScriptをブックマークしたものです。

普通はURLをブックマークするに対し、JavaScriptをブックマークします。

そしてこのブックマークを選ぶときは保存されたJavaScriptが実行されます。

iPhoneのブラウザ関連のアプリでは結構使われています。

最下部へ移動するJavaScriptをiPhoneに登録する方法

javascript:window.scrollTo(0,document.documentElement.scrollHeight);
  • まずSafariで任意のサイトをブックマークする
  • そのブックマークを編集する
  • 一行名に好きな名前(ここではPage Bottom)を記入し、二行目を上記のJavaScriptを貼付けで保存する

f:id:kinopyo:20091128002653p:image

  • ページの最下部へ移動したい時はブックマークからさっき登録したブックマークレットをタップすればOK。

f:id:kinopyo:20091128002655p:image


参考サイト:

http://css-eblog.com/javascript/scrolltoend-for-iphone.html

ブックマークレットとは – はてなキーワード

Same-Originポリシー勉強メモ

2009年11月23日

gihyoサイトの「ここが危ない!Web2.0のセキュリティ」連載の第2回:「Same-Originポリシーと迂回技術」の勉強メモです。

定義

他のドメインのサイトへはリクエストを送信できない制限のことをSame-Originポリシーと呼びます。同じドメインであってもポート番号やプロトコル(HTTPとHTTPSなど)が異なれば,異なるサイト(クロスドメイン)とみなされアクセスできません。クロスドメインアクセスは機能として実装されていないのではなく,セキュリティ上の理由から禁止されているそうです。

必要性

俺があの黒の攻撃者とし、攻撃目標がユーザのメールアカウント情報だとします。もしクロスドメインにアクセスする制限がなければ、事前に用意したスクリプトで(urlをメールサーバに設定)メールアカウントの情報が取得できるようになってしまいます。(この辺りはCookieの話が出てきます)

ウェブの基本ルール

Ajaxだけではなく、フレームやサブウインドウの情報にアクセスする場合などにも存在する

クロスドメインでデータを取得する方法

* リバースPorxy

* SCRIPTタグ(JSONP)

* Flash

* 画像

* スタイルシート

リバースProxy

データ提供サーバにとってユーザの身元は隠れているため、攻撃者に利用しやすい

ユーザの身元を確認しようとすると、ユーザ情報を扱わなければならない

ユーザ情報–>サーバ–>データ提供サーバ

 

JSONPの動作原理、jQueryでJSONPを利用

2009年11月21日

前回の記事の続きとしてJSONPを勉強しました。

XMLHttpRequestはセキュリティ上の制限により、

クロスドメインの通信ができないです。

でもウェブサービスのようなどうしてもクロスドメインで通信したい場合があります。

その時の手段してあげられるのがこのScriptタグです。

(他の手段としてiframeやflashとリバースプロキシがあるそうです)

JSONPとは

これを一番分かりやすく説明してくれたのははてなキーワードだと思います。

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に含める際には十分な注意が必要である。

JSONPとは – はてなキーワード


動作原理

やはりソースコードで読むほうが早いだと思います。

以下gihyo.netからのサンプルコードです。

クライアント側
<html>
<body>
<script>
function callback(x){ // コールバック関数を定義
alert(x["name"]);
}
</script>
<script src="http://mail.example.com/json.dat"></script>
</body>
</html>
データ提供サーバ側が用意したJSON

json.datの中身

callback( { "name" : "Fukumori" } );


簡単まとめ

要はクライアント側で先にデータを扱うコールバック関数を定義

その名はデータの提供側とのコールバック関数名と一致する必要がある

scriptタグでデータ提供サーバのデータをインポート

すると先に用意したコールバック関数が走ってデータを処理する


もっと詳しい動作原理とセキュリティはgihyoの特集を参照してください。

とても分かりやすいです。おすすめ!

ここが危ない!Web2.0のセキュリティ:第3回 JSONPでのクロスドメインアクセス|gihyo.jp … 技術評論社


jQueryでJSONPを使う

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.

http://docs.jquery.com/Ajax/jQuery.getJSON#urldatacallback

利用方法はurlの最後に”?”付きのコールバックパラメータを追加することです。

例えば”example.com?callback=?”こんな感じです。

callbackの値は指定しなくてもよいみたい、

jQueryが自動で変換してくれます。

ただしコールバックのパラメータ名はデータ提供側によって異なるかもしれません。

例えばヤフーPipesは”_callback=?”を要求してるそうです。

IE JavaScript実行した際の「アクセスが拒否されました」メッセージ

2009年11月19日

経緯

iframeで動的に画面を読み込む際URL不正などによる通信エラーが起こした場合の

エラーハンドラを追加したかったので判断するロジックが必要でした。

わざと誤ったURLを渡して検証しましたが、以下のコードはだめでした。


// documentがnullかと思ってそれで判断しようとしたんです。
if (this.contentWindow.document) {}

現象

あるプロパティは存在しているのに、アクセスができない。コードで書くと

// プロパティがオブジェクトに存在するかを判断
// ここはアラーとが出した、つまり存在したってこと
if ("aProperty" in obj) alert('obj has aProperty');
// 次にそのオブジェクトにアクセスしようとすると
// エラーになった
obj.aProperty

IE8の開発ツールで見たら「アクセスが拒否されました」と書いてある。

f:id:kinopyo:20091119133655j:image


エラーをcatch

判断のロジックをtry-catch文に書けばいいです。

try {
this.contentWindow.document;
} catch (e) {
if (e.number == -2147024891) {
//アクセスが拒否されました。
alert(e.message);
} else {
alert("別のメッセージ");
}
}


参考サイト:http://sei.qee.jp/docs/freetalk/2009/02.html

JavaScript: argumentsは配列じゃない、配列のメソッドを使うには

2009年11月18日

argumentsは配列じゃないため、配列のメソッドは

使えません。ということは本を読んだとき当たり前だと思ったんですが、

実際コードに落としたときは

自然とargument.slice()を書いちゃいました。

argumentsで配列のメソッドを使うには

Array.prototype.<配列のメソッド>.call(arguments,<パラメータ>)

Array.prototype.slice.call(arguments,2)

上記の意図としてはarguments.slice(2)の表現に近いです。

argumentsはarray-likeオブジェクト

ここでちょっとargumentsの基本知識を復習します。

length属性もあるし、[]でindex指定のオブジェクトを参照できますけど、

argumentsは配列に似ているオブジェクトだけです。

予約語

Technically, argumentsは予約語ではないですが、

予約語として認識してよいです。

つまりargumentsという変数は作成しないでってことです。


function foo(x){
alert(x);
var arguments;
arguments[0] = null;	//xの値が変更されちゃう
alert(x);	// null が出力される
}
callee Property

Refers to the function that is currently being executed.

今実行中のファクションを参照しています。

function(x) {
if (x <= 1) return 1;
return x * arguments.callee(x-1);
}


 

クライアント側のActiveXが有効か無効かを検出するJavaScript

2009年11月17日

知っておくべきこと

  • ActiveXはIE専用のものと理解してよい、Firefoxなどでは存在しない
  • new ActiveXObject(“Microsoft.XMLHTTP”)でIEのXMLHttpRequestが生成される
    • IE のバージョンによっては、”Microsoft.XMLHTTP”の代わりにこれらも使用できるそうです:
    • “Msxml2.XMLHTTP.5.0″
    • “Msxml2.XMLHTTP.4.0″
    • “Msxml2.XMLHTTP.3.0″
    • “Msxml2.XMLHTTP”
  • もし生成できればActiveXコントロールは有効になっている


検出ソースコード

// ブラウザがIEの場合
if (window.ActiveXObject) {
try {
//IEのXMLHttpRequestオブジェクトを試しに生成
var xhr = new ActiveXObject("Microsoft.XMLHTTP");
} catch (e) {
alert('ActiveXコントロールは無効になっています');
}
}


参考サイト

動画をHTMLに埋め込むヒント – faireal.net

今更のAjax基本:XMLHttpRequestについて

2009年11月13日

前記

恥ずかしいことに今仕事でjQueryでばりばりAjaxを使ってますが、

実際はただjQueryの便利なAPIを使っただけで

Ajaxそのものの仕組みも分かっていません。


今更ですが、その辺の基礎知識を勉強しできるだけ誰にも分かるように

自分が理解したことをメモとして残したいです。


XMLHttpRequestとは

JavaScriptなどのウェブブラウザ搭載のスクリプト言語で、サーバとのHTTP通信を行うための組み込みオブジェクト(API)である。

すでに読み込んだページからさらにHTTPリクエストを発することができ、ページ遷移することなしにデータを送受信できるAjaxの基幹技術である。

XMLHttpRequest – Wikipedia

なるほど、これがAjaxを支える基幹ですね。

JavaScriptのオブジェクトです。

名前にXMLがついていますが、XML以外のデータも扱うことができます。

XMLHttpRequestの歴史

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 – Wikipedia

ようは各ブラウザが先にXMLHttpRequestオブジェクトを実装した、

そして偉い人がAjaxを提唱してから一気に有名になった訳ですよね。


XMLHttpRequestの仕組み

AllAboutの記事に載ってた仕組みを自分で書きました。

f:id:kinopyo:20091114023141j:image

XMLHttpRequestのメソッドやプロパティは多分これからも使うことはありませんが、

一応図で見て大体把握しておきましょう。

openメソッドはイニシャライズみたいな感じで、GETかPOSTか、URLなどのパラメータを受け取ります。

そしてsendメソッドによるサーバに送信する前に、onreadystatechangeイベントのコールバックでステータスを判断しresponseTextやresponseXML プロパティのデータを返す流れですね。

拡張機能から XMLHttpRequest を使いたい場合は、非同期でロードするようにすべきです。

非同期の使用法では、データを受け取ったときにコールバックを受け取ります。

そのため、リクエストが発生している間はブラウザは通常どおりに動き続けます。

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() を使用。

http://ponpon-village.net/ajax/xmlhttp.htm

非同期通信のサンプルコード

  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です。


注意点

  • file:/// および ftp:// は HTTP ステータスを返しません。そのため、status についてはゼロが、statusText については空文字列を返されます。
  • XMLHttpRequestは、セキュリティを考慮して、リクエストを送信できるのは同一ドメイン内に制限されています。


とりあえず自分が気になった点を書きました。

肝心なところはonreadystatechangeでのコールバックだと思います。

次回

XMLHttpRequestは同一ドメイン内に制限されていますね。

別のドメインとのやり取りはどう行うのかを次のテーマにします。

なんかJSONPとかクロスドメインなどのキーワードがよく見えますが、

その辺をはっきりしようと思います。

参考サイト:

XMLHttpRequest – Wikipedia

XMLHttpRequest – MDC

Ajaxはじめの一歩 XMLHttpRequest – [JavaScript]All About