ในขั้นตอนนี้ คุณจะได้เรียนรู้เกี่ยวกับสิ่งต่อไปนี้
- วิธีโหลดทรัพยากรจากภายนอกแอปและเพิ่มลงใน DOM ผ่าน XHR และ ObjectURL
เวลาโดยประมาณในการทำขั้นตอนนี้คือ 20 นาที
หากต้องการดูตัวอย่างสิ่งที่คุณจะทำในขั้นตอนนี้ ให้เลื่อนลงไปที่ด้านล่างของหน้านี้ ↓
CSP ส่งผลต่อการใช้ทรัพยากรภายนอกอย่างไร
แพลตฟอร์มแอป Chrome จะบังคับให้แอปของคุณปฏิบัติตามนโยบายรักษาความปลอดภัยเนื้อหา (CSP) โดยสมบูรณ์ คุณไม่สามารถโหลดทรัพยากร DOM เช่น รูปภาพ แบบอักษร และ CSS จากภายนอกแอป Chrome ได้โดยตรง ใหม่
หากต้องการแสดงรูปภาพภายนอกในแอป คุณจะต้องส่งคำขอผ่าน XMLHttpRequest
เปลี่ยนรูปแบบเป็น Blob แล้วสร้าง ObjectURL สามารถเพิ่ม ObjectURL
นี้ลงใน
DOM เพราะอ้างถึงรายการในหน่วยความจำในบริบทของแอป
แสดงภาพขนาดย่อของรายการสิ่งที่ต้องทำ
มาเปลี่ยนแอปให้มองหา URL รูปภาพในรายการสิ่งที่ต้องทำกัน หาก URL ดูเหมือนรูปภาพ (สำหรับ ตัวอย่างเช่น ลงท้ายด้วย .png, .jpg, .svg หรือ .gif) ให้ใช้กระบวนการที่กล่าวไว้ข้างต้นเพื่อแสดง รูปภาพขนาดย่อที่อยู่ถัดจาก URL
อัปเดตสิทธิ์
ในแอป Chrome คุณสามารถเรียก XMLHttpRequest ไปยัง URL ใดก็ได้ตราบใดที่คุณระบุโดเมนของ URL นั้นใน
ไฟล์ Manifest เนื่องจากคุณไม่ทราบล่วงหน้าว่าผู้ใช้จะพิมพ์ URL รูปภาพใด คุณจึงควรขออนุญาต
ส่งคำขอไปยัง "<all_urls>"
ใน manifest.json ให้พิมพ์ "
"permissions": ["storage", "alarms", "notifications",
"webview", "<all_urls>"],
สร้างและล้าง ObjectURL
ใน controller.js ให้เพิ่มเมธอด _createObjectURL()
เพื่อสร้าง ObjectURL จาก Blob
Controller.prototype._createObjectURL = function(blob) {
var objURL = URL.createObjectURL(blob);
this.objectURLs = this.objectURLs || [];
this.objectURLs.push(objURL);
return objURL;
};
ObjectURL จะเก็บหน่วยความจำอยู่ ดังนั้นเมื่อคุณไม่จำเป็นต้องใช้ ObjectURL แล้ว คุณควรเพิกถอนคำขอเหล่านั้น เพิ่มรายการนี้
_clearObjectURL()
ไปยัง controller.js เพื่อจัดการกับ:
Controller.prototype._clearObjectURL = function() {
if (this.objectURLs) {
this.objectURLs.forEach(function(objURL) {
URL.revokeObjectURL(objURL);
});
this.objectURLs = null;
}
};
ส่งคำขอ XHR
เพิ่มเมธอด _requestRemoteImageAndAppend()
เพื่อเรียกใช้ XMLHttpRequest ใน URL ของรูปภาพที่ระบุ:
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 เมธอดนี้จะสร้าง ObjectURL
จากการตอบสนองของ XHR และเพิ่มองค์ประกอบ <img>
ที่มี ObjectURL
นี้ไปยัง DOM
แยกวิเคราะห์ URL รูปภาพในรายการสิ่งที่ต้องทำ
ตอนนี้ให้เพิ่มเมธอด _parseForImageURLs()
ที่ค้นหาลิงก์ทั้งหมดที่ยังไม่ได้ประมวลผลและตรวจสอบลิงก์เหล่านั้น
รูปภาพ สำหรับ URL แต่ละรายการที่มีลักษณะเหมือนรูปภาพ ให้เรียกใช้คำสั่ง _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]);
}
}
};
แสดงภาพขนาดย่อในรายการสิ่งที่ต้องทำ
โทรหา _parseForImageURLs()
จาก showAll()
, showActive()
และ showCompleted()
ในขณะนี้:
/**
* 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;
}
เปิดแอป Todo ที่เสร็จสมบูรณ์แล้ว
คุณดำเนินการขั้นตอนที่ 5 เสร็จแล้ว โหลดแอปของคุณซ้ำและเพิ่มรายการสิ่งที่ต้องทำที่มี URL ไปยังรูปภาพที่โฮสต์ออนไลน์ ใช้บ้าง URL ที่คุณใช้ได้: http://goo.gl/nqHMF#.jpg หรือ http://goo.gl/HPBGR#.png
สำหรับข้อมูลเพิ่มเติม
หากต้องการข้อมูลโดยละเอียดเพิ่มเติมเกี่ยวกับ API บางรายการที่นำมาใช้ในขั้นตอนนี้ โปรดดูที่
พร้อมก้าวต่อไปหรือยัง ไปที่ขั้นตอนที่ 6 - ส่งออกสิ่งที่ต้องทำไปยังระบบไฟล์ »