Chrome 應用程式安全性模型禁止在 iframe 和使用內嵌內容中使用外部內容
編寫指令碼和 eval()
。您可以覆寫這些限制,但您的外部內容必須
獨立於應用程式之外
隔離內容無法直接存取應用程式的資料或任何 API。使用跨來源 XMLHttpRequest 和訊息後的訊息,用於在活動頁面和沙箱內容之間進行通訊。 間接存取 API
參照外部資源
應用程式使用的「內容安全政策」不允許使用許多類型的遠端網址,
無法直接參照應用程式頁面上的外部圖片、樣式表或字型。不過,您可以
使用跨來源 XMLHttpRequests 擷取這些資源,再透過 blob:
網址提供。
資訊清單規定
如要執行跨來源 XMLHttpRequests,您需要為遠端網址的 主機:
"permissions": [
"...",
"https://supersweetdomainbutnotcspfriendly.com/"
]
跨來源 XMLHttpRequest
將遠端網址擷取到應用程式,並以 blob:
網址提供內容:
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://supersweetdomainbutnotcspfriendly.com/image.png', true);
xhr.responseType = 'blob';
xhr.onload = function(e) {
var img = document.createElement('img');
img.src = window.URL.createObjectURL(this.response);
document.body.appendChild(img);
};
xhr.send();
您可能會想在本機儲存這些資源,以便在離線時使用。
嵌入外部網頁
webview
標記可讓您在應用程式嵌入外部網路內容,例如網站
頁面。並取代指向遠端網址的 iframe,因為 Chrome 應用程式已停用這類 iframe。取消喜歡
iframe 時,webview
標記會在獨立的程序中執行。也就是說,其中的漏洞攻擊
則一律隔離,且無法取得進階權限。此外,由於儲存空間
(Cookie 等) 與應用程式隔離,網頁內容無法存取
應用程式的資料。
新增 WebView 元素
您的 webview
元素必須包含來源內容的網址並指定其尺寸。
<webview src="http://news.google.com/" width="640" height="480"></webview>
更新房源
如要動態變更 webview
標記的 src
、width
和 height
屬性,可以採取下列任一做法:
直接在 JavaScript 物件上設定這些屬性,或使用 setAttribute
DOM 函式。
document.querySelector('#mywebview').src =
'http://blog.chromium.org/';
// or
document.querySelector('#mywebview').setAttribute(
'src', 'http://blog.chromium.org/');
沙箱本機內容
沙箱功能可讓指定頁面在沙箱機制的專屬來源中提供。然後這些網頁就會
不受其「內容安全政策」規範。沙箱模式可以使用 iframe、內嵌指令碼和
eval()
。請參閱 sandbox 的資訊清單欄位說明。
但請留意,沙箱網頁不能使用 Chrome*。相互整合如果需要執行以下操作:
eval()
,使用此路徑即可免除 CSP 的約束,但您將無法使用許多超酷的新項目。
在沙箱中使用內嵌指令碼
以下為採用內嵌指令碼和 eval()
的沙箱網頁範例:
<html>
<body>
<h1>Woot</h1>
<script>
eval('console.log(\'I am an eval-ed inline script.\')');
</script>
</body>
</html>
在資訊清單中加入沙箱
您必須在資訊清單中加入 sandbox
欄位,並列出要在
沙箱:
"sandbox": {
"pages": ["sandboxed.html"]
}
在視窗中開啟沙箱頁面
您可以建立一個視窗,在其他應用程式頁面上開啟,就像任何其他應用程式頁面一樣。請參考 會建立兩個視窗的範例,一個用於未採用沙箱機制的主應用程式視窗,另一個用於 採用沙箱機制的網頁:
chrome.app.runtime.onLaunched.addListener(function() {
chrome.app.window.create('window.html', {
'bounds': {
'width': 400,
'height': 400,
'left': 0,
'top': 0
}
});
chrome.app.window.create('sandboxed.html', {
'bounds': {
'width': 400,
'height': 400,
'left': 400,
'top': 0
}
});
});
在應用程式頁面中嵌入沙箱模式頁面
您也可以使用 iframe
,將沙箱頁面嵌入其他應用程式頁面中:
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<p>I am normal app window.</p>
<iframe src="sandboxed.html" width="300" height="200"></iframe>
</body>
</html>
傳送訊息至沙箱頁面
傳送訊息分為兩個部分:您需要透過寄件者頁面/視窗張貼訊息。 並在接收頁面/視窗中監聽訊息
張貼訊息
您可以使用 postMessage
在應用程式和沙箱內容之間進行通訊。請看看
背景指令碼會將訊息張貼至沙箱開啟的頁面:
var myWin = null;
chrome.app.runtime.onLaunched.addListener(function() {
chrome.app.window.create('sandboxed.html', {
'bounds': {
'width': 400,
'height': 400
}
}, function(win) {
myWin = win;
myWin.contentWindow.postMessage('Just wanted to say hey.', '*');
});
});
一般而言,您會想要指定傳送訊息的確切來源。 Chrome 應用程式無法存取沙箱內容的專屬來源,因此您只能將所有內容加入許可清單 做為可接受的來源 (「*」)。在接收端上,您通常會想檢查來源。 但由於 Chrome 應用程式已經包含內容,因此使用者並非必要。若要瞭解詳情,請參閱 window.postMessage.
聽取訊息並回覆
以下是新增到沙箱頁面的訊息接收器範例:
var messageHandler = function(event) {
console.log('Background script says hello.', event.data);
// Send a reply
event.source.postMessage(
{'reply': 'Sandbox received: ' + event.data}, event.origin);
};
window.addEventListener('message', messageHandler);
詳情請參閱沙箱範例。