jQueryのloadメソッドのこと
jQuery[v1.4.2]のloadメソッドで2度もはまったのでメモ。
これ。$(selector).load(url,data,callback)
このurlの書式がセレクタ有り無しの場合でレスポンスの挙動が変わる。
結論から
セレクタ有りでloadすると、レスポンス内のscriptが抜かれる。
サンプル
以下サンプルはdataとcallbackは使用しないパターンとして省略。
この場合、windowの読み込みが完了したときに"/foo/bar #hoge"を非同期でリクエストして
結果を#resに流しこむ。
■アクセスする側の部分的コード
<div id="res"> </div> <script> $(window).bind('load',function(){ var url='/foo/bar #hoge'; //#hogeの内容を取ってきて $('#res').load(url); }); </script>
アクセス先にセレクタ指定があるときは、レスポンス内容のscriptが抜かれる。(2回目)
jQuery[v1.4.2]のload辺りを見てみる
var sb = J(), tb = /<script(.|\s)*?\/script>/gi, ub = /select|textarea/i, vb = /color|date|datetime|email|hidden|month|number|password|range|search|tel|text|time|url|week/i, N = /=\?(&|$)/, ka = /\?/, wb = /(\?|&)_=.*?(&|$)/, xb = /^(\w+:)?\/\/([^\/?#]+)/, yb = /%20/g, zb = c.fn.load; c.fn.extend({load: function(a, b, d) { if (typeof a !== "string") return zb.call(this, a); else if (!this.length) return this; var f = a.indexOf(" "); if (f >= 0) { var e = a.slice(f, a.length); a = a.slice(0, f) } f = "GET"; if (b) if (c.isFunction(b)) { d = b; b = null } else if (typeof b === "object") { b = c.param(b, c.ajaxSettings.traditional); f = "POST" } var j = this; c.ajax({url: a,type: f,dataType: "html",data: b,complete: function(i, o) { if (o === "success" || o === "notmodified") j.html(e ? c("<div />").append(i.responseText.replace(tb, "")).find(e) : i.responseText); d && j.each(d, [i.responseText, o, i]) }}); return this },
周辺のことはともかく、まず注目する部分。
j.html(e ? c("<div />").append(i.responseText.replace(tb, "")).find(e) : i.responseText);
レスポンスを返す時に、eをチェックしている。
eは何?
var f = a.indexOf(" "); if (f >= 0) { var e = a.slice(f, a.length); a = a.slice(0, f) }
アクセス先のURLに半角スペースがあれば、eにセレクタ相応部分の文字列を格納している。
立ち戻る。
j.html(e ? c("<div />").append(i.responseText.replace(tb, "")).find(e) : i.responseText);
eが存在する(true)とき、responseText内のtbを空文字列に置換した上で、
新しい空divに、セレクタ要素を流しこむ。
tbは最初に宣言してあったね。
tb = /<script(.|\s)*?\/script>/gi,
というわけでscript抜かれる。
まとめ
loadメソッドではセレクタ無しではscript抜かれず、セレクタ有りではscriptが抜かれる。
※ちなみにv1.8.2での当該ソース部分でのコメント
// inject the contents of the document in, removing the scripts // to avoid any 'Permission Denied' errors in IE
なんで抜かれるん!って思ったけどちょっと分かった。
要するに、もしセレクタ内のscriptを取得してしまうと、
セレクタ範囲外におけるscriptとの依存関係が不明で、
動作保証できないし危険だということだと思う。