<script> 從 DOM 移除的行為(Fwd: [whatwg] Behavior when <script> is removed from DOM)

轉一個有趣的討論串。來源:http://lists.whatwg.org/htdig.cgi/whatwg-
whatwg.org /2011-December/thread.html#34031

這個討論串從討論的流程是這樣:

* 把 <script> 加到 DOM 裡再執行前移除的兼容行為[1]
* 為什麼會前端會想要移除 <script> → 主要是為了取消 JSONP 讀入
* 如果 XHR 支援跨來源 JSONP 就可以用 XHR 的各種功能取消 JSONP 了

因此 Mozilla 開發者 Jonas Sicking 有了一個 xhr.responseType = "jsonp";
的提案 — 如果回傳的內容可以以 JSONP 解析,就無視跨來源策略,其中最大的好
處就是不需要在全局物件上註冊函數而 xhr.response 會直接給出解析而不是運算
得來的 JS 物件,另外就是也不需要加上 CORS  Header,畢竟很多情形下要改
HTTP Header 好像非常的困難(就像大家抱怨 AppCache 要求
text/cache-manifest 一樣,現在標準已經不要求這個了)。

Google 的知名 ECMAScript 專家 Mark Miller 覺得說有一個穿透跨來源策略的特
殊值不是很好,問說能不能 xhr 回傳值是能用 JS 解析就允許跨來源,然後就討
論到可以從 xhr 得到 JS 到底有沒有比從 <script> 得到 JS 的資訊量多的有趣
問題。有些講到 ES3 的我不是很懂,不過好像因為有
Function.prototype.toString,所以 xhr 得到的 JS 比 <script> 的資訊量多在
「註解」而已(局部變數的名稱也可以靠 Function.prototype.toString 得到。
Function.prototype.toString 也是一個 implementation-dependent 的坑,不過
應該沒有瀏覽器會回傳註解...)。不過 Jonas Sicking 是說這個方案被採用的
話,隨便人都可以擷取本來是同來源的伺服器 <-> 瀏覽器 xhr JSON 溝通。(所
以剛剛那邊除了「註解」也外應該還包括在函數外沒被賦值的表達式 :p)

所以總之,以後 xhr 應該就可以弄跨來源的 JSONP 了。Jonas 是說他覺得
xhr.responseType="jsonp" 很醜(hideous),所以如果有人有什麼這個 API 的
命名建議的話可以提一下(可能可以 xhr.responseType = "json"; 再
xhr.enableJSONP(); 之類的... 不過感覺還是一句 xhr.responseType="jsonp"
簡單。大家怎麼想?)

(除了開頭的連結之外,我也把討論連結加到翻譯一半的 XMLHttpRequest 規範
[3]了,希望增加規範翻譯的價值。歡迎大家陸續加入!)

[1] 這個部份的規範是[2],也蠻值得翻譯的,目前只有 FF 在這裡符合規範。
[2]
http://www.whatwg.org/specs/web-apps/current-work/multipage/scripting-1.html#script-processing-src-prepare
[3] http://www.w3.org/html/ig/zh/wiki/XMLHttpRequest

此致

呂 康豪(Kenny), 中文興趣小組W3C連絡人
Google+: https://plus.google.com/112088462407783855918/posts
新浪微博: http://t.sina.com.cn/1950042164

(11/12/08 9:20), Jonas Sicking wrote:
> On Wed, Dec 7, 2011 at 3:55 PM, Yehuda Katz <wycats@gmail.com> wrote:
>> Yehuda Katz
>> (ph) 718.877.1325
>>
>>
>> On Wed, Dec 7, 2011 at 3:43 PM, Jonas Sicking <jonas@sicking.cc> wrote:
>>> On Wed, Dec 7, 2011 at 12:39 PM, Yehuda Katz <wycats@gmail.com> wrote:
>>>> Yehuda Katz
>>>> (ph) 718.877.1325
>>>>
>>>>
>>>> On Wed, Dec 7, 2011 at 12:29 PM, Boris Zbarsky <bzbarsky@mit.edu> wrote:
>>>>
>>>>> On 12/7/11 3:22 PM, Joshua Bell wrote:
>>>>>
>>>>>> This can't be implemented in JS today (e.g. as a shim) since that
>>>>>> "evaluate
>>>>>> this script text in this new global sandbox" bit isn't present.
>>>>>>
>>>>> It can sort of be done via opening a new window and setting its opener
>>>>> to
>>>>> null before injecting some <script> tags into it.  Modulo popup
>>>>> blockers
>>>>> and crappy user experience, of course....
>>>>
>>>> Or evaluating the script inside a worker, perhaps?
>>> Workers aren't great sandboxes. They already have access to shared
>>> workers and XHR. Soon they will get access to IndexedDB too. So
>>> there's lots of damage they can cause.
>>>
>>> If we want to run untrusted code then I think we need to have an API
>>> specifically designed for that.
>>>
>>> If we want an API for loading JSONP data apart from the sandbox (which
>>> I think is needed), then we should have an API specifically designed
>>> for that. It's possible that we can reuse XHR here and just adjust the
>>> security model when the returned data is JSONP.
>>
>> You would at least want to execute them in a lexical scope containing the
>> callback, so that the callback did not need to be installed on the global
>> scope.
> Ideally we wouldn't execute anything. We'd just parse the JSON literal
> and hand that back. That is what'll give us safety.
>
> To make a concrete, but hideous, example:
>
> We could add xhr.responseType = "jsonp".
>
> When this is set, the XHR object will look for contents on the following form:
>
> <js identifier> '(' <js-literal> ')'
>
> followed by an optional ';'
>
> When the contents follows that syntax, the XHR object parses the
> js-literal and sets it's .response property to the result.
>
> Other than that the XHR object works just as it currently does. I.e.
> it fires progress events, load events and readystatechange events as
> normal.
>
> This way no JS execution happens, and no global names need to be set
> up. The <js identifier> part is simply ignored other than to check
> that it's a valid js identifier.
>
> I believe we can come up with something better than this, but it's a
> demonstration of what's technically feasible.
>
> / Jonas
>

Received on Thursday, 22 December 2011 20:44:48 UTC