在此步骤中,您将学习以下内容:
- 如何从应用外部加载资源,并通过 XHR 和 Object网址 将其添加到 DOM。
完成此步骤预计用时:20 分钟。
若要预览您将在此步骤中完成的内容,请跳转到本页底部 ↓。
CSP 如何影响外部资源的使用
Chrome 应用平台强制您的应用完全符合内容安全政策 (CSP)。 您无法直接从 Chrome 应用外部加载 DOM 资源(例如图片、字体和 CSS) 软件包。
如果您希望在应用中显示外部图片,则需要通过 XMLHttpRequest 请求,
将其转换为 Blob,然后创建 ObjectURL。您可以将此ObjectURL
添加到
DOM,因为它指的是应用上下文中的内存项。
显示待办事项的缩略图
让我们更改应用,以在待办事项中查找图片网址。如果网址看起来像 (例如以 .png、.jpg、.svg 或 .gif 结尾),请按照上述流程展示 图片缩略图。
更新权限
在 Chrome 应用中,您可以对任何网址进行 XMLHttpRequest 调用,只要您在
。由于您不会事先知道用户将输入什么图片网址,因此请求权限以
向 "<all_urls>"
发出请求。
在 manifest.json 中,请求“
"permissions": ["storage", "alarms", "notifications",
"webview", "<all_urls>"],
创建和清除 Object网址
在 controller.js 中,添加 _createObjectURL()
方法以从 Blob 创建 Object网址:
Controller.prototype._createObjectURL = function(blob) {
var objURL = URL.createObjectURL(blob);
this.objectURLs = this.objectURLs || [];
this.objectURLs.push(objURL);
return objURL;
};
Object网址 会保留内存,因此当不再需要 Object网址 时,应撤销它们。添加此项
_clearObjectURL()
方法添加到 controller.js 以处理上述操作:
Controller.prototype._clearObjectURL = function() {
if (this.objectURLs) {
this.objectURLs.forEach(function(objURL) {
URL.revokeObjectURL(objURL);
});
this.objectURLs = null;
}
};
发出 XHR 请求
添加 _requestRemoteImageAndAppend()
方法以对给定的图片网址执行 XMLHttpRequest:
Controller.prototype._requestRemoteImageAndAppend = function(imageUrl, element) {
var xhr = new XMLHttpRequest();
xhr.open('GET', imageUrl);
xhr.responseType = 'blob';
xhr.onload = function() {
var img = document.createElement('img');
img.setAttribute('data-src', imageUrl);
img.className = 'icon';
var objURL = this._createObjectURL(xhr.response);
img.setAttribute('src', objURL);
element.appendChild(img);
}.bind(this);
xhr.send();
};
在 XHR 加载时,此方法会根据 XHR 的响应创建 ObjectURL
,并添加 <img>
元素
将此 ObjectURL
添加到 DOM。
解析待办事项中的图片网址
现在添加 _parseForImageURLs()
方法,用于查找所有尚未处理的链接,并检查它们是否存在
图片。对于每个看起来像图片的网址,执行 _requestRemoteImageAndAppend()
:
Controller.prototype._parseForImageURLs = function () {
// remove old blobs to avoid memory leak:
this._clearObjectURL();
var links = this.$todoList.querySelectorAll('a[data-src]:not(.thumbnail)');
var re = /\.(png|jpg|jpeg|svg|gif)$/;
for (var i = 0; i<links.length; i++) {
var url = links[i].getAttribute('data-src');
if (re.test(url)) {
links[i].classList.add('thumbnail');
this._requestRemoteImageAndAppend(url, links[i]);
}
}
};
在待办事项列表中呈现缩略图
现在,从 showAll()
、showActive()
和 showCompleted()
调用 _parseForImageURLs()
:
/**
* An event to fire on load. Will get all items and display them in the
* todo-list
*/
Controller.prototype.showAll = function () {
this.model.read(function (data) {
this.$todoList.innerHTML = this._parseForURLs(this.view.show(data));
this._parseForImageURLs();
}.bind(this));
};
/**
* Renders all active tasks
*/
Controller.prototype.showActive = function () {
this.model.read({ completed: 0 }, function (data) {
this.$todoList.innerHTML = this._parseForURLs(this.view.show(data));
this._parseForImageURLs();
}.bind(this));
};
/**
* Renders all completed tasks
*/
Controller.prototype.showCompleted = function () {
this.model.read({ completed: 1 }, function (data) {
this.$todoList.innerHTML = this._parseForURLs(this.view.show(data));
this._parseForImageURLs();
}.bind(this));
};
对 editItem()
执行相同的操作:
Controller.prototype.editItem = function (id, label) {
...
var onSaveHandler = function () {
...
if (value.length && !discarding) {
...
label.innerHTML = this._parseForURLs(value);
this._parseForImageURLs();
} else if (value.length === 0) {
...
}
限制显示的图片尺寸
最后,在 _bowercomponents/todomvc-common/base.css 中添加 CSS 规则,以限制 图片:
.thumbnail img[data-src] {
max-width: 100px;
max-height: 28px;
}
启动完成的待办事项应用
您已完成第 5 步!重新加载应用,然后添加待办事项,并提供指向在线托管图片的网址。部分 您可以使用的网址:http://goo.gl/nqHMF#.jpg 或 http://goo.gl/HPBGR#.png。
了解详情
如需详细了解此步骤中引入的一些 API,请参阅:
准备好继续下一步了吗?转到第 6 步 - 将待办事项导出到文件系统 »