OLD | NEW |
1 <h1>Embed Content</h1> | 1 <h1>Embed Content</h1> |
2 | 2 |
3 | 3 |
4 <p> | 4 <p> |
5 The <a href="app_architecture.html#security">packaged apps security model</a> di
sallows | 5 The <a href="app_architecture.html#security">packaged apps security model</a> di
sallows |
6 external content in iframes and | 6 external content in iframes and |
7 the use of inline scripting and <code>eval()</code>. | 7 the use of inline scripting and <code>eval()</code>. |
8 You can override these restrictions, | 8 You can override these restrictions, |
9 but your external content must be isolated from the app. | 9 but your external content must be isolated from the app. |
10 </p> | 10 </p> |
(...skipping 17 matching lines...) Expand all Loading... |
28 <h2 id="external">Referencing external resources</h2> | 28 <h2 id="external">Referencing external resources</h2> |
29 | 29 |
30 <p> | 30 <p> |
31 The <a href="app_csp.html">Content Security Policy</a> used by apps disallows | 31 The <a href="app_csp.html">Content Security Policy</a> used by apps disallows |
32 the use of many kinds of remote URLs, so you can't directly reference external | 32 the use of many kinds of remote URLs, so you can't directly reference external |
33 images, stylesheets, or fonts from an app page. Instead, you can use use | 33 images, stylesheets, or fonts from an app page. Instead, you can use use |
34 cross-origin XMLHttpRequests to fetch these resources, | 34 cross-origin XMLHttpRequests to fetch these resources, |
35 and then serve them via <code>blob:</code> URLs. | 35 and then serve them via <code>blob:</code> URLs. |
36 </p> | 36 </p> |
37 | 37 |
38 <h3>Manifest requirement</h3> | 38 <h3 id="manifest">Manifest requirement</h3> |
39 | 39 |
40 <p> | 40 <p> |
41 To be able to do cross-origin XMLHttpRequests, you'll need to add a permission | 41 To be able to do cross-origin XMLHttpRequests, you'll need to add a permission |
42 for the remote URL's host: | 42 for the remote URL's host: |
43 </p> | 43 </p> |
44 | 44 |
45 <pre> | 45 <pre> |
46 "permissions": [ | 46 "permissions": [ |
47 "...", | 47 "...", |
48 "https://supersweetdomainbutnotcspfriendly.com/" | 48 "https://supersweetdomainbutnotcspfriendly.com/" |
49 ] | 49 ] |
50 </pre> | 50 </pre> |
51 | 51 |
52 <h3>Cross-origin XMLHttpRequest</h3> | 52 <h3 id="cross-origin">Cross-origin XMLHttpRequest</h3> |
53 | 53 |
54 <p> | 54 <p> |
55 Fetch the remote URL into the app and serve its contents as a <code>blob:</code> | 55 Fetch the remote URL into the app and serve its contents as a <code>blob:</code> |
56 URL: | 56 URL: |
57 </p> | 57 </p> |
58 | 58 |
59 <pre> | 59 <pre> |
60 var xhr = new XMLHttpRequest(); | 60 var xhr = new XMLHttpRequest(); |
61 xhr.open('GET', 'https://supersweetdomainbutnotcspfriendly.com/image.png', true)
; | 61 xhr.open('GET', 'https://supersweetdomainbutnotcspfriendly.com/image.png', true)
; |
62 xhr.responseType = 'blob'; | 62 xhr.responseType = 'blob'; |
(...skipping 21 matching lines...) Expand all Loading... |
84 <p> | 84 <p> |
85 The <code>browser</code> tag allows you to embed external web content in your | 85 The <code>browser</code> tag allows you to embed external web content in your |
86 app, for example, a web page. It replaces iframes that point to remote URLs, | 86 app, for example, a web page. It replaces iframes that point to remote URLs, |
87 which are disabled inside packaged apps. Unlike iframes, the | 87 which are disabled inside packaged apps. Unlike iframes, the |
88 <code>browser</code> tag runs in a separate process. This means that an exploit | 88 <code>browser</code> tag runs in a separate process. This means that an exploit |
89 inside of it will still be isolated and won't be able to gain elevated | 89 inside of it will still be isolated and won't be able to gain elevated |
90 privileges. Further, since its storage (cookies, etc.) is isolated from the app, | 90 privileges. Further, since its storage (cookies, etc.) is isolated from the app, |
91 there is no way for the web content to access any of the app's data. | 91 there is no way for the web content to access any of the app's data. |
92 </p> | 92 </p> |
93 | 93 |
94 <h3>Add browser element</h3> | 94 <h3 id="browser_element">Add browser element</h3> |
95 | 95 |
96 <p> | 96 <p> |
97 Your <code>browser</code> element must include the URL to the source content | 97 Your <code>browser</code> element must include the URL to the source content |
98 and specify its dimensions. | 98 and specify its dimensions. |
99 </p> | 99 </p> |
100 | 100 |
101 <pre><browser src="http://news.google.com/" width="640" height="480"></bro
wser></pre> | 101 <pre><browser src="http://news.google.com/" width="640" height="480"></bro
wser></pre> |
102 | 102 |
103 <h3>Update properties</h3> | 103 <h3 id="properties">Update properties</h3> |
104 | 104 |
105 <p> | 105 <p> |
106 To dynamically change the <code>src</code>, <code>width</code> and | 106 To dynamically change the <code>src</code>, <code>width</code> and |
107 <code>height</code> properties of a <code>browser</code> tag, you can either | 107 <code>height</code> properties of a <code>browser</code> tag, you can either |
108 set those properties directly on the JavaScript object, or use the | 108 set those properties directly on the JavaScript object, or use the |
109 <code>setAttribute</code> DOM function. | 109 <code>setAttribute</code> DOM function. |
110 </p> | 110 </p> |
111 | 111 |
112 <pre> | 112 <pre> |
113 document.querySelector('#mybrowser').src = | 113 document.querySelector('#mybrowser').src = |
(...skipping 16 matching lines...) Expand all Loading... |
130 </p> | 130 </p> |
131 | 131 |
132 <p> | 132 <p> |
133 It's a trade-off though: | 133 It's a trade-off though: |
134 sandboxed pages can't use the chrome.* APIs. | 134 sandboxed pages can't use the chrome.* APIs. |
135 If you need to do things like <code>eval()</code>, | 135 If you need to do things like <code>eval()</code>, |
136 go this route to be exempt from CSP, | 136 go this route to be exempt from CSP, |
137 but you won't be able to use the cool new stuff. | 137 but you won't be able to use the cool new stuff. |
138 </p> | 138 </p> |
139 | 139 |
140 <h3>Use inline scripts in sandbox</h3> | 140 <h3 id="inline_scripts">Use inline scripts in sandbox</h3> |
141 | 141 |
142 <p> | 142 <p> |
143 Here's a sample sandboxed page | 143 Here's a sample sandboxed page |
144 which uses an inline script and <code>eval()</code>: | 144 which uses an inline script and <code>eval()</code>: |
145 </p> | 145 </p> |
146 | 146 |
147 <pre> | 147 <pre> |
148 <html> | 148 <html> |
149 <body> | 149 <body> |
150 <h1>Woot</h1> | 150 <h1>Woot</h1> |
151 <script> | 151 <script> |
152 document.write('I am an inline script.<br>'); | 152 document.write('I am an inline script.<br>'); |
153 eval('document.write(\'I am an eval-ed inline script.\');'); | 153 eval('document.write(\'I am an eval-ed inline script.\');'); |
154 </script> | 154 </script> |
155 </body> | 155 </body> |
156 </html> | 156 </html> |
157 </pre> | 157 </pre> |
158 | 158 |
159 <h3>Include sandbox in manifest</h3> | 159 <h3 id="include_sandbox">Include sandbox in manifest</h3> |
160 | 160 |
161 <p> | 161 <p> |
162 You need to include the <code>sandbox</code> field in the manifest | 162 You need to include the <code>sandbox</code> field in the manifest |
163 and list the app pages to be served in a sandbox: | 163 and list the app pages to be served in a sandbox: |
164 </p> | 164 </p> |
165 | 165 |
166 <pre> | 166 <pre> |
167 "sandbox": { | 167 "sandbox": { |
168 "pages": ["sandboxed.html"] | 168 "pages": ["sandboxed.html"] |
169 } | 169 } |
170 </pre> | 170 </pre> |
171 | 171 |
172 <h3>Opening a sandboxed page in a window</h3> | 172 <h3 id="opening_sandbox">Opening a sandboxed page in a window</h3> |
173 | 173 |
174 <p> | 174 <p> |
175 Just like any other app pages, | 175 Just like any other app pages, |
176 you can create a window that the sandboxed page opens in. | 176 you can create a window that the sandboxed page opens in. |
177 Here's a sample that creates two windows, | 177 Here's a sample that creates two windows, |
178 one for the main app window that isn't sandboxed, | 178 one for the main app window that isn't sandboxed, |
179 and one for the sandboxed page: | 179 and one for the sandboxed page: |
180 </p> | 180 </p> |
181 | 181 |
182 <pre> | 182 <pre> |
183 chrome.experimental.app.onLaunched.addListener(function() { | 183 chrome.experimental.app.onLaunched.addListener(function() { |
184 chrome.app.window.create('window.html', { | 184 chrome.app.window.create('window.html', { |
185 'width': 400, | 185 'width': 400, |
186 'height': 400, | 186 'height': 400, |
187 'left': 0, | 187 'left': 0, |
188 'top': 0 | 188 'top': 0 |
189 }); | 189 }); |
190 | 190 |
191 chrome.app.window.create('sandboxed.html', { | 191 chrome.app.window.create('sandboxed.html', { |
192 'width': 400, | 192 'width': 400, |
193 'height': 400, | 193 'height': 400, |
194 'left': 400, | 194 'left': 400, |
195 'top': 0 | 195 'top': 0 |
196 }); | 196 }); |
197 }); | 197 }); |
198 </pre> | 198 </pre> |
199 | 199 |
200 <h3>Embedding a sandboxed page in an app page</h3> | 200 <h3 id="embedding_sandbox">Embedding a sandboxed page in an app page</h3> |
201 | 201 |
202 <p>Sandboxed pages can also be embedded within another app page | 202 <p>Sandboxed pages can also be embedded within another app page |
203 using an <code>iframe</code>:</p> | 203 using an <code>iframe</code>:</p> |
204 | 204 |
205 <pre> | 205 <pre> |
206 <!DOCTYPE html> | 206 <!DOCTYPE html> |
207 <html> | 207 <html> |
208 <head> | 208 <head> |
209 </head> | 209 </head> |
210 <body> | 210 <body> |
211 <p>I am normal app window.</p> | 211 <p>I am normal app window.</p> |
212 | 212 |
213 <iframe src="sandboxed.html" width="300" height="200"></iframe> | 213 <iframe src="sandboxed.html" width="300" height="200"></iframe> |
214 </body> | 214 </body> |
215 </html> | 215 </html> |
216 </pre> | 216 </pre> |
217 | 217 |
218 | 218 |
219 <h2 id="postMessage">Sending messages to sandboxed pages</h2> | 219 <h2 id="postMessage">Sending messages to sandboxed pages</h2> |
220 | 220 |
221 <p> | 221 <p> |
222 There are two parts to sending a message: | 222 There are two parts to sending a message: |
223 you need to post a message from the sender page/window, | 223 you need to post a message from the sender page/window, |
224 and listen for messages on the receiving page/window. | 224 and listen for messages on the receiving page/window. |
225 </p> | 225 </p> |
226 | 226 |
227 <h3>Post message</h3> | 227 <h3 id="post_message">Post message</h3> |
228 | 228 |
229 <p> | 229 <p> |
230 You can use <code>postMessage</code> to communicate | 230 You can use <code>postMessage</code> to communicate |
231 between your app and sandboxed content. | 231 between your app and sandboxed content. |
232 Here's a sample background script | 232 Here's a sample background script |
233 that posts a message to the sandboxed page it | 233 that posts a message to the sandboxed page it |
234 opens: | 234 opens: |
235 </p> | 235 </p> |
236 | 236 |
237 <pre> | 237 <pre> |
(...skipping 19 matching lines...) Expand all Loading... |
257 so you can only whitelist all origins | 257 so you can only whitelist all origins |
258 as acceptable origins ('*'). | 258 as acceptable origins ('*'). |
259 On the receiving end, | 259 On the receiving end, |
260 you generally want to check the origin; | 260 you generally want to check the origin; |
261 but since packaged apps content is contained, | 261 but since packaged apps content is contained, |
262 it isn't necessary. | 262 it isn't necessary. |
263 To find out more, | 263 To find out more, |
264 see <a href="https://developer.mozilla.org/en/DOM/window.postMessage">window.pos
tMessage</a>. | 264 see <a href="https://developer.mozilla.org/en/DOM/window.postMessage">window.pos
tMessage</a>. |
265 </p> | 265 </p> |
266 | 266 |
267 <h3>Listen for message</h3> | 267 <h3 id="listen_message">Listen for message</h3> |
268 | 268 |
269 <p> | 269 <p> |
270 Here's a sample message receiver | 270 Here's a sample message receiver |
271 that gets added to your sandboxed page: | 271 that gets added to your sandboxed page: |
272 </p> | 272 </p> |
273 | 273 |
274 <pre> | 274 <pre> |
275 var messageHandler = function(e) { | 275 var messageHandler = function(e) { |
276 console.log('Background script says hello.', e.data); | 276 console.log('Background script says hello.', e.data); |
277 }; | 277 }; |
278 | 278 |
279 window.addEventListener('message', messageHandler); | 279 window.addEventListener('message', messageHandler); |
280 </pre> | 280 </pre> |
281 | 281 |
282 <p class="backtotop"><a href="#top">Back to top</a></p> | 282 <p class="backtotop"><a href="#top">Back to top</a></p> |
OLD | NEW |