跨域傳輸信息postMessage


widnow.postMessage()方法允許安全的跨域傳輸。

Syntax

otherWindow.postMessage(message, targetOrigin, [transfer]);
otherWindow
指向另一個窗口的引用:。
message
傳輸給另一個窗口的信息
targetOrigin
一個字符串,指定消息來源(URL形式)。記住總是提供一個特定的URL地址如果你知道的話,不要總是使用“*”(針對所有的URL),因為指定一個特定的URL可以防止惡意的網站來攻擊。

The dispatched event

其他的窗口可以通過以下代碼來監聽被發送的信息:

window.addEventListener("message", receiveMessage, false);

function receiveMessage(event)
{
  var origin = event.origin || event.originalEvent.origin; // For Chrome, the origin property is in the event.originalEvent object.
  if (origin !== "http://example.org:8080")
    return;

  // ...
}

被發送的信息的屬性如下:

data
從其他窗口傳遞的data
origin
當postMessage調用的時候,發送信息窗口的origin。這個字符串是協議和"://"和主機名和后面用":"連接了一個接口名稱,如果這個接口名和默認的接口名不一樣的話。比如http://example.org(默認的接口是443),http://example.net(默認的接口是80)和http://example.com:8080。注意,這個origin並不一定要是當前亦或未來的那個窗口的origin,所以這將有可能當調用postMessage的時候,導致跳轉到另一個完全不同的地址。
source
發送信息的window對象。你可以使用這個在不同origin之間在兩個窗口之間建立兩個通信。

Security concerns

如果你不想接受到其他網站的信息,不要在message對象上增加任何監聽。

使用origin(有可能也會使用source)屬性來確定發送者的身份,如果你不想接受到其他網站的信息的話。

任何的window(包括,例如http://evil.example.com)可以向任何的其他window發送信息,你沒有任何的保障來保證未知的發送者不會發送惡意的信息。確保了發送信息者的身份之后,你還需要確驗證接收到的內容的語法。否則,發送信任信息的受信網站可能在你的網站上創建一個跨域的腳本漏洞。

不要使用“*”,而是確定的目標origin,當你使用postMessage來發送信息給其他的windows的時候,防止其他網站在你postMessage的時候攔截發送的信息。

Example

/*
 * In window A's scripts, with A being on <http://example.com:8080>:
 */

var popup = window.open(...popup details...);

// When the popup has fully loaded, if not blocked by a popup blocker:

// This does nothing, assuming the window hasn't changed its location.
popup.postMessage("The user is 'bob' and the password is 'secret'",
                  "https://secure.example.net");

// This will successfully queue a message to be sent to the popup, assuming
// the window hasn't changed its location.
popup.postMessage("hello there!", "http://example.org");

function receiveMessage(event)
{
  // Do we trust the sender of this message?  (might be
  // different from what we originally opened, for example).
  if (event.origin !== "http://example.org")
    return;

  // event.source is popup
  // event.data is "hi there yourself!  the secret response is: rheeeeet!"
}
window.addEventListener("message", receiveMessage, false);
/*
 * In the popup's scripts, running on <http://example.org>:
 */

// Called sometime after postMessage is called
function receiveMessage(event)
{
  // Do we trust the sender of this message?
  if (event.origin !== "http://example.com:8080")
    return;

  // event.source is window.opener
  // event.data is "hello there!"

  // Assuming you've verified the origin of the received message (which
  // you must do in any case), a convenient idiom for replying to a
  // message is to call postMessage on event.source and provide
  // event.origin as the targetOrigin.
  event.source.postMessage("hi there yourself!  the secret response " +
                           "is: rheeeeet!",
                           event.origin);
}

window.addEventListener("message", receiveMessage, false);

 

Notes

任何window可以在任何其他的window上使用這個方法,在任何的時候,不管當前頁面在window中的location,來發送信息。

所以,任何的對象監聽被使用來接受信息時必須先檢查信息發送着的身份,使用origin和可能使用的屬性source來判斷。

這個必須再三聲明:不檢查origin和source可能會導致跨站點腳本攻擊。

和任何的異步執行的腳本(timeout,用戶生成的腳本),調用postMessage來監聽何時事件處理函數監聽postMessage發送的事件對象是不可能的,將會拋出錯誤。

發送對象的origin屬性是不會受到當前在調用窗口的document.domain值的影響。

 

For IDN host names only, the value of the origin property is not consistently Unicode or punycode; for greatest compatibility check for both the IDN and punycode values when using this property if you expect messages from IDN sites. This value will eventually be consistently IDN, but for now you should handle both IDN and punycode forms.

The value of the origin property when the sending window contains a javascript: or data:URL is the origin of the script that loaded the URL.

Using window.postMessage in extensions 

window.postMessage is available to JavaScript running in chrome code (e.g., in extensions and privileged code), but the source property of the dispatched event is always null as a security restriction. (The other properties have their expected values.) The targetOrigin argument for a message sent to a window located at a chrome: URL is currently misinterpreted such that the only value which will result in a message being sent is "*". Since this value is unsafe when the target window can be navigated elsewhere by a malicious site, it is recommended thatpostMessage not be used to communicate with chrome: pages for now; use a different method (such as a query string when the window is opened) to communicate with chrome windows. Lastly, posting a message to a page at a file: URL currently requires that the targetOriginargument be "*"file:// cannot be used as a security restriction; this restriction may be modified in the future.

Browser compatibility

Feature Chrome Firefox (Gecko) Internet Explorer Opera Safari (WebKit)
Basic support 1.0 6.0 (6.0)[1]
8.0 (8.0)[2]
8.0[3]
10.0[4]
9.5 4.0
transferargument ? 20.0 (20.0) Not supported ? ?

 

[1] Prior to Gecko 6.0 (Firefox 6.0 / Thunderbird 6.0 / SeaMonkey 2.3), the message parameter must be a string. Starting in Gecko 6.0 (Firefox 6.0 / Thunderbird 6.0 / SeaMonkey 2.3), themessage parameter is serialized using the structured clone algorithm. This means you can pass a broad variety of data objects safely to the destination window without having to serialize them yourself.

[2] Gecko 8.0 introduced support for sending File and FileList objects between windows. This is only allowed if the recipient's principal is contained within the sender's principal for security reasons.

[3] IE8 and IE9 only support it for <frame> and <iframe>.

[4] IE10 has important limitations: see this article for details.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM