תוכן חיצוני

מודל האבטחה של אפליקציות Chrome מונע שימוש בתוכן חיצוני במסגרות iframe, ואסור להשתמש בסקריפטים מוטבעים וב-eval(). אפשר לבטל את ההגבלות האלה, אבל התוכן החיצוני שלכם חייב להיות מבודד מהאפליקציה.

לתוכן מבודד לא תהיה גישה ישירה לנתוני האפליקציה או לממשקי ה-API. שימוש ב-XMLHttpRequests ובהעברת הודעות ממקורות שונים כדי לתקשר בין דף האירוע לתוכן בארגז החול ולגשת לממשקי ה-API באופן עקיף.

הפניות למשאבים חיצוניים

לפי Content Security Policy שאפליקציות משתמשות בו, לא ניתן להשתמש בסוגים רבים של כתובות URL מרוחקות, ולכן אי אפשר להפנות ישירות לתמונות חיצוניות, לגיליונות סגנונות ולגופנים מדף האפליקציה. במקום זאת, אפשר להשתמש ב-XMLHttpRequests ממקורות שונים כדי לאחזר את המשאבים האלה, ואז להציג אותם באמצעות כתובות URL מסוג blob:.

דרישה למניפסט

כדי לבצע בקשות XMLHttpRequests בין מקורות, צריך להוסיף הרשאה למארח של כתובת ה-URL המרוחקת:

"permissions": [
    "...",
    "https://supersweetdomainbutnotcspfriendly.com/"
  ]

XMLHttpRequest בין מקורות

מאחזרים את כתובת ה-URL המרוחקת לאפליקציה ומציגים את התוכן שלה ככתובת URL של 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 שמפנות לכתובות URL מרוחקות, שמושבתות באפליקציות Chrome. בניגוד למסגרות iframe, התג webview פועל בתהליך נפרד. כלומר, ניצול של התשתית הפנימית עדיין יהיה מבודד ולא יוכל לקבל הרשאות מורחבות. בנוסף, מאחר שהאחסון שלו (קובצי cookie וכו') מבודד מהאפליקציה, אין לתוכן באינטרנט גישה לנתוני האפליקציה.

הוספה של רכיב WebView

הרכיב webview צריך לכלול את כתובת ה-URL של תוכן המקור ולציין את המידות שלו.

<webview src="http://news.google.com/" width="640" height="480"></webview>

עדכון נכסים

כדי לשנות באופן דינמי את המאפיינים src, width ו-height של תג webview, אפשר להגדיר את המאפיינים האלה ישירות באובייקט ה-JavaScript, או להשתמש בפונקציה setAttribute DOM.

document.querySelector('#mywebview').src =
    'http://blog.chromium.org/';
// or
document.querySelector('#mywebview').setAttribute(
    'src', 'http://blog.chromium.org/');

תוכן מקומי ב-Sandbox

'ארגז חול' מאפשר להציג דפים ספציפיים במקור ייחודי שנמשך בארגז החול. לאחר מכן הדפים האלה פטורים ממדיניות Content Security Policy שלהם. בדפים בארגז חול אפשר להשתמש ב-iframes, בסקריפטים מוטבעים וב-eval(). קוראים את התיאור של שדה המניפסט ב-sandbox.

אבל אפשר להפסיק להשתמש ב-Chrome במקרה של התנגשות: דפים שפועלים בארגז חול לא יכולים להשתמש ב-Chrome.* ממשקי API. אם צריך לבצע פעולות כמו eval(), יש לעבור למסלול הזה כדי לקבל פטור מ-CSP אבל לא להשתמש בדברים החדשים והמגניבים.

שימוש בסקריפטים מוטבעים ב-Sandbox

הנה דוגמה לדף בארגז חול שמשתמש בסקריפט מוטבע וב-eval():

<html>
  <body>
    <h1>Woot</h1>
    <script>
      eval('console.log(\'I am an eval-ed inline script.\')');
    </script>
  </body>
</html>

הכללת Sandbox במניפסט

צריך לכלול את השדה sandbox במניפסט ולציין את דפי האפליקציות שיוצגו ב-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
    }
  });
});

הטמעה של דף בארגז חול בדף אפליקציה

ניתן גם להטמיע דפים שנוצרו בארגז חול (Sandbox) בתוך דף אפליקציה אחר באמצעות 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);

לפרטים נוספים, אפשר לעיין בדוגמה של sandbox.