Nội dung bên ngoài

Mô hình bảo mật Ứng dụng Chrome không cho phép nội dung bên ngoài trong iframe cũng như sử dụng tập lệnh cùng dòng và eval(). Bạn có thể ghi đè các hạn chế này, nhưng phải tách riêng nội dung bên ngoài với ứng dụng.

Nội dung bị tách biệt không thể truy cập trực tiếp vào dữ liệu của ứng dụng hoặc bất kỳ API nào. Hãy sử dụng XMLHttpRequests trên nhiều nguồn gốc và thông báo sau để giao tiếp giữa trang sự kiện và nội dung trong hộp cát, đồng thời truy cập gián tiếp vào các API.

Tham chiếu các tài nguyên bên ngoài

Chính sách bảo mật nội dung mà các ứng dụng sử dụng không cho phép sử dụng nhiều loại URL từ xa, vì vậy, bạn không thể trực tiếp tham chiếu hình ảnh, biểu định kiểu hoặc phông chữ bên ngoài từ một trang ứng dụng. Thay vào đó, bạn có thể sử dụng XMLHttpRequests trên nhiều nguồn gốc để tìm nạp những tài nguyên này rồi phân phát qua các URL blob:.

Yêu cầu về tệp kê khai

Để có thể thực hiện XMLHttpRequests trên nhiều nguồn gốc, bạn sẽ cần thêm quyền cho máy chủ lưu trữ của URL từ xa:

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

XMLHttpRequest trên nhiều nguồn gốc

Tìm nạp URL từ xa vào ứng dụng và phân phát nội dung của URL dưới dạng 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();

Bạn nên lưu những tài nguyên này để sử dụng khi không có mạng.

Nhúng trang web bên ngoài

Thẻ webview cho phép bạn nhúng nội dung web bên ngoài vào ứng dụng của mình, chẳng hạn như một trang web. API này thay thế các iframe trỏ đến các URL từ xa bị vô hiệu hóa trong Ứng dụng Chrome. Không giống như iframe, thẻ webview chạy trong một quy trình riêng. Điều này có nghĩa là một hoạt động khai thác bên trong đó sẽ vẫn bị tách biệt và sẽ không thể giành được đặc quyền cấp cao. Ngoài ra, vì bộ nhớ của ứng dụng (cookie, v.v.) được tách riêng với ứng dụng nên không có cách nào để nội dung trên web truy cập vào bất kỳ dữ liệu nào của ứng dụng.

Thêm phần tử WebView

Phần tử webview của bạn phải chứa URL đến nội dung nguồn và chỉ định các phương diện của phần tử đó.

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

Cập nhật cơ sở lưu trú

Để thay đổi linh động các thuộc tính src, widthheight của thẻ webview, bạn có thể đặt các thuộc tính đó trực tiếp trên đối tượng JavaScript hoặc sử dụng hàm DOM setAttribute.

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

Nội dung cục bộ trong hộp cát

Chế độ hộp cát cho phép các trang đã chỉ định được phân phát ở một nguồn gốc riêng biệt, có hộp cát. Sau đó, các trang này sẽ được miễn tuân theo Chính sách bảo mật nội dung của Google. Các trang hộp cát có thể dùng iframe, tập lệnh cùng dòng và eval(). Hãy xem nội dung mô tả trường trong tệp kê khai cho sandbox.

Đó là một sự đánh đổi: các trang có hộp cát không thể sử dụng Chrome.* API. Nếu bạn cần thực hiện những việc như eval(), hãy làm theo cách này để được miễn CSP, nhưng bạn sẽ không thể sử dụng các nội dung thú vị mới.

Sử dụng tập lệnh cùng dòng trong hộp cát

Dưới đây là một trang mẫu có hộp cát sử dụng tập lệnh cùng dòng và eval():

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

Đưa hộp cát vào tệp kê khai

Bạn cần đưa trường sandbox vào tệp kê khai và liệt kê các trang ứng dụng được phân phát trong một hộp cát:

"sandbox": {
  "pages": ["sandboxed.html"]
}

Mở trang có hộp cát trong cửa sổ

Giống như bất kỳ trang ứng dụng nào khác, bạn có thể tạo một cửa sổ để mở trang hộp cát. Dưới đây là mẫu tạo ra hai cửa sổ, một cửa sổ cho cửa sổ ứng dụng chính không có hộp cát và một cửa sổ cho trang có hộp cát:

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
    }
  });
});

Nhúng trang hộp cát vào trang ứng dụng

Bạn cũng có thể nhúng các trang trong hộp cát vào một trang ứng dụng khác bằng cách sử dụng 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>

Gửi thư đến trang hộp cát

Có hai phần để gửi thư: bạn cần đăng thông báo từ trang/cửa sổ người gửi và lắng nghe thư trên trang/cửa sổ nhận.

Đăng tin nhắn

Bạn có thể sử dụng postMessage để giao tiếp giữa ứng dụng của mình và nội dung trong hộp cát. Dưới đây là một tập lệnh nền mẫu sẽ đăng thông báo lên trang hộp cát mà thông báo đó mở ra:

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.', '*');
     });
});

Nói chung trên web, bạn nên chỉ định nguồn gốc chính xác mà thư được gửi đi. Ứng dụng Chrome không có quyền truy cập vào nguồn gốc duy nhất của nội dung hộp cát, vì vậy, bạn chỉ có thể đưa tất cả các nguồn gốc vào danh sách cho phép là nguồn gốc được chấp nhận ("*"). Khi nhận, bạn thường muốn kiểm tra nguồn gốc; nhưng do có chứa nội dung Ứng dụng Chrome nên việc này là không cần thiết. Để tìm hiểu thêm, hãy xem phần window.postMessage.

Nghe tin nhắn và trả lời

Dưới đây là trình nhận thông báo mẫu sẽ được thêm vào trang hộp cát của bạn:

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);

Để biết thêm chi tiết, hãy xem mẫu sandbox.