Index: chrome/common/extensions/docs/server2/templates/articles/app_external.html |
diff --git a/chrome/common/extensions/docs/server2/templates/articles/app_external.html b/chrome/common/extensions/docs/server2/templates/articles/app_external.html |
new file mode 100644 |
index 0000000000000000000000000000000000000000..93ab7a1f9ebf3f5ed9fe89d1898159852b59c721 |
--- /dev/null |
+++ b/chrome/common/extensions/docs/server2/templates/articles/app_external.html |
@@ -0,0 +1,229 @@ |
+<h1 class="page_title">Embed Content</h1> |
+<p> |
+The <a href="app_architecture.html#security">packaged apps security model</a> disallows |
+external content in iframes and |
+the use of inline scripting and <code>eval()</code>. |
+You can override these restrictions, |
+but your external content must be isolated from the app. |
+</p> |
+<p> |
+Isolated content cannot directly |
+access the app's data or any of the APIs. |
+Use cross-origin XMLHttpRequests |
+and post-messaging to communicate between the event page and sandboxed content |
+and indirectly access the APIs. |
+</p> |
+<p class="note"> |
+<b>API Samples: </b> |
+Want to play with the code? |
+Check out the |
+<a href="https://github.com/GoogleChrome/chrome-app-samples/tree/master/eval-in-iframe">eval-in-iframe</a> |
+and <a href="https://github.com/GoogleChrome/chrome-app-samples/tree/master/regex-tester">regex-tester</a> samples. |
+</p> |
+<h2 id="external">Referencing external resources</h2> |
+<p> |
+The <a href="app_csp.html">Content Security Policy</a> used by apps disallows |
+the use of many kinds of remote URLs, so you can't directly reference external |
+images, stylesheets, or fonts from an app page. Instead, you can use use |
+cross-origin XMLHttpRequests to fetch these resources, |
+and then serve them via <code>blob:</code> URLs. |
+</p> |
+<h3>Manifest requirement</h3> |
+<p> |
+To be able to do cross-origin XMLHttpRequests, you'll need to add a permission |
+for the remote URL's host: |
+</p> |
+<pre> |
+"permissions": [ |
+ "...", |
+ "https://supersweetdomainbutnotcspfriendly.com/" |
+ ] |
+</pre> |
+<h3>Cross-origin XMLHttpRequest</h3> |
+<p> |
+Fetch the remote URL into the app and serve its contents as a <code>blob:</code> |
+URL: |
+</p> |
+<pre> |
+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.webkitURL.createObjectURL(this.response); |
+ document.body.appendChild(img); |
+}; |
+xhr.send(); |
+</pre> |
+<p>You may want to <a href="offline_apps.html#saving-locally">save</a> |
+these resources locally, so that they are available offline.</p> |
+<h2 id="browsertag">Embed external web pages</h2> |
+<p class="note"> |
+<b>API Sample: </b> |
+Want to play with the code? Check out the |
+<a href="https://github.com/GoogleChrome/chrome-app-samples/tree/master/browser-tag">browser-tag</a> |
+sample. |
+</p> |
+<p> |
+The <code>browser</code> tag allows you to embed external web content in your |
+app, for example, a web page. It replaces iframes that point to remote URLs, |
+which are disabled inside packaged apps. Unlike iframes, the |
+<code>browser</code> tag runs in a separate process. This means that an exploit |
+inside of it will still be isolated and won't be able to gain elevated |
+privileges. Further, since its storage (cookies, etc.) is isolated from the app, |
+there is no way for the web content to access any of the app's data. |
+</p> |
+<h3>Add browser element</h3> |
+<p> |
+Your <code>browser</code> element must include the URL to the source content |
+and specify its dimensions. |
+</p> |
+<pre><browser src="http://news.google.com/" width="640" height="480"></browser></pre> |
+<h3>Update properties</h3> |
+<p> |
+To dynamically change the <code>src</code>, <code>width</code> and |
+<code>height</code> properties of a <code>browser</code> tag, you can either |
+set those properties directly on the JavaScript object, or use the |
+<code>setAttribute</code> DOM function. |
+</p> |
+<pre> |
+document.querySelector('#mybrowser').src = |
+ 'http://blog.chromium.org/'; |
+// or |
+document.querySelector('#mybrowser').setAttribute( |
+ 'src', 'http://blog.chromium.org/'); |
+</pre> |
+<h2 id="sandboxing">Sandbox local content</h2> |
+<p> |
+Sandboxing allows specified pages |
+to be served in a sandboxed, unique origin. |
+These pages are then exempt from their Content Security Policy. |
+Sandboxed pages can use iframes, inline scripting, |
+and <code>eval()</code>. |
+Check out the manifest field description for |
+<a href="manifest.html#sandbox">sandbox</a>. |
+</p> |
+<p> |
+It's a trade-off though: |
+sandboxed pages can't use the chrome.* APIs. |
+If you need to do things like <code>eval()</code>, |
+go this route to be exempt from CSP, |
+but you won't be able to use the cool new stuff. |
+</p> |
+<h3>Use inline scripts in sandbox</h3> |
+<p> |
+Here's a sample sandboxed page |
+which uses an inline script and <code>eval()</code>: |
+</p> |
+<pre> |
+<html> |
+ <body> |
+ <h1>Woot</h1> |
+ <script> |
+ document.write('I am an inline script.<br>'); |
+ eval('document.write(\'I am an eval-ed inline script.\');'); |
+ </script> |
+ </body> |
+</html> |
+</pre> |
+<h3>Include sandbox in manifest</h3> |
+<p> |
+You need to include the <code>sandbox</code> field in the manifest |
+and list the app pages to be served in a sandbox: |
+</p> |
+<pre> |
+"sandbox": { |
+ "pages": ["sandboxed.html"] |
+} |
+</pre> |
+<h3>Opening a sandboxed page in a window</h3> |
+<p> |
+Just like any other app pages, |
+you can create a window that the sandboxed page opens in. |
+Here's a sample that creates two windows, |
+one for the main app window that isn't sandboxed, |
+and one for the sandboxed page: |
+</p> |
+<pre> |
+chrome.experimental.app.onLaunched.addListener(function() { |
+ chrome.app.window.create('window.html', { |
+ 'width': 400, |
+ 'height': 400, |
+ 'left': 0, |
+ 'top': 0 |
+ }); |
+ chrome.app.window.create('sandboxed.html', { |
+ 'width': 400, |
+ 'height': 400, |
+ 'left': 400, |
+ 'top': 0 |
+ }); |
+}); |
+</pre> |
+<h3>Embedding a sandboxed page in an app page</h3> |
+<p>Sandboxed pages can also be embedded within another app page |
+ using an <code>iframe</code>:</p> |
+<pre> |
+<!DOCTYPE html> |
+<html> |
+<head> |
+</head> |
+ <body> |
+ <p>I am normal app window.</p> |
+ <iframe src="sandboxed.html" width="300" height="200"></iframe> |
+ </body> |
+</html> |
+</pre> |
+<h2 id="postMessage">Sending messages to sandboxed pages</h2> |
+<p> |
+There are two parts to sending a message: |
+you need to post a message from the sender page/window, |
+and listen for messages on the receiving page/window. |
+</p> |
+<h3>Post message</h3> |
+<p> |
+You can use <code>postMessage</code> to communicate |
+between your app and sandboxed content. |
+Here's a sample background script |
+that posts a message to the sandboxed page it |
+opens: |
+</p> |
+<pre> |
+var myWin = null; |
+chrome.experimental.app.onLaunched.addListener(function() { |
+ chrome.app.window.create('sandboxed.html', { |
+ 'width': 400, |
+ 'height': 400 |
+ }, function(win) { |
+ myWin = win; |
+ myWin.postMessage('Just wanted to say hey.', '*'); |
+ }); |
+}); |
+</pre> |
+<p> |
+Generally speaking on the web, |
+you want to specify the exact origin |
+from where the message is sent. |
+Packaged apps have no access |
+to the unique origin of sandboxed content, |
+so you can only whitelist all origins |
+as acceptable origins ('*'). |
+On the receiving end, |
+you generally want to check the origin; |
+but since packaged apps content is contained, |
+it isn't necessary. |
+To find out more, |
+see <a href="https://developer.mozilla.org/en/DOM/window.postMessage">window.postMessage</a>. |
+</p> |
+<h3>Listen for message</h3> |
+<p> |
+Here's a sample message receiver |
+that gets added to your sandboxed page: |
+</p> |
+<pre> |
+var messageHandler = function(e) { |
+ console.log('Background script says hello.', e.data); |
+}; |
+window.addEventListener('message', messageHandler); |
+</pre> |
+<p class="backtotop"><a href="#top">Back to top</a></p> |