2013-12-11 31 views
2

我想使用window.addEventListener("message",myOnmessageCallback,false)接收來自我的window本身的郵件。 (這是說我不想不必要地使myOnmessageCallback函數容易從其他來源接收惡意消息(我認爲這可能是其他框架,瀏覽器Windows,選項卡,父級和內置頁框,對嗎?)安全使用window.postMessage,是「if(event.source!== window){return;}」好嗎?

所以我覺得,如果這避免不是我window碰到任何物體本身。

 
function myOnmessageCallback(event) 
{ 
    if(event.orign !== window) 
    { 
    // I assume the message is from not this window here, therefore ignore it. 
    return; 
    } 

    //do some useful stuff with the message received (only from window) 
} 

這個問題似乎一個很好的方式,以減少myOnmessageCallback回調只是處理 信息通過網頁本身的window.postMessage()送?

PS:對於那些想爲什麼我希望減少postMessageonmessage能力的人。我想有一種方法可以將某些東西放入Javascript執行隊列中,從而允許在兩者之間處理UI東西。我會用經典的window.setTimeout,但是這個時間最短,我不想不必要地浪費時間。

+0

「setTimeout()」實際上會變得明顯嗎? – jfriend00

+0

@ jfriend00是的,我擔心這可能是一個問題,因爲頻率。我希望能夠讓腳本平滑(不會阻塞UI等),所以我必須推遲發佈腳本經常返回到Javascript執行隊列的內容。我希望有'window.setImmediate()'。 – humanityANDpeace

+0

[polyfill setImmediate.js](https://github.com/NobleJS/setImmediate/blob/master/setImmediate.js)中的人似乎得出結論,僅僅檢查窗口是不夠的。他們使用一些Math.random()UUID類來確保。這更讓我懷疑...... – humanityANDpeace

回答

5

event.origin不是窗口對象。這是一個URI。

event.source是源窗口對象。

它不會出現,你可以限制信息是隻能從自己,如果你檢查:

event.source === window 

的MDN文檔的postMessage的狀態是:

任何窗口可以在任何訪問這個方法其他窗口,在任何時候, 不管文檔在窗口中的位置,向它發送一個 消息。因此,任何用於接收消息 的事件偵聽器都必須首先使用 來源以及可能的源屬性檢查消息發件人的身份。這不能被低估: 未能檢查來源和可能的來源屬性使 跨站點腳本攻擊。

我將解釋這意味着您應該檢查event.origin是否至少匹配您的域,甚至可能與您的確切URL匹配,如果您只希望將消息發送到同一個窗口。

你可以用代碼檢查這兩個產地和來源是這樣的:

window.addEventListener("message", function(e) { 
    if (window.location.href.indexOf(e.origin) === 0 && e.source === window) { 
     // passed safety check, OK to process here 
     console.log("passed"); 
    } 
}); 

工作演示:http://jsfiddle.net/jfriend00/j3A8k/


我不知道你在這裏過於複雜的事情儘量節省4ms的與setTimeout() 。從MDN頁的postMessage:

如果您不希望從其他站點接收郵件,請不要在消息事件添加 任何事件偵聽器。這是一種完全可以避免安全問題的萬無一失的方法。


在你的意見,你似乎表明你這樣做了很多,這就是爲什麼你擔心爲4ms。你還沒有說出你想要解決的實際問題是什麼,但你應該能夠做一些有意義的工作(例如工作幾秒鐘),然後用setTimeout()產生收益,然後做更多的工作。或者,如果你真的想在後臺工作,webWorkers可能是一個更好的方式來做到這一點。

+0

謝謝你的回答。我最後也喜歡你的建議。我想過的所有事情。 F **** ng IE8垃圾使得很難採用Web工具,並且仍然有10%(2013年12月)不是智能用戶,並堅持IE8(我不明白)。所以更好的選擇似乎不在那裏(我真的希望我可以使用它們:)。現在我想我會在建議的檢查中以「良好的信任」去做。 – humanityANDpeace

+0

@humanityANDpeace - 我添加了一個代碼示例來說明如何檢查e.origin和e.source。請注意,'e.origin'只是源的域,而不是完整的路徑。 – jfriend00

+0

對!這應該允許另一個安全測試。我不知道爲什麼[setImmediate.js](https://github.com/NobleJS/setImmediate)中的人們爲什麼實現了一些「Math.random」nonce事情......看起來他們實際上關心的是性能。因此,如果這裏構想的解決方案是「子彈頭」,我想知道他們爲什麼要做所有這些額外的工作,以確保信息不是來自別處。 – humanityANDpeace