In questo passaggio, imparerai:
- Come caricare risorse dall'esterno dell'app e aggiungerle al DOM tramite XHR e ObjectURLs.
Tempo stimato per completare questo passaggio: 20 minuti.
Per visualizzare l'anteprima di ciò che completerai in questo passaggio, vai alla fine di questa pagina ↓.
In che modo CSP influisce sull'utilizzo di risorse esterne
La piattaforma App di Chrome impone la conformità completa della tua app ai Criteri di sicurezza del contenuto (CSP). Non puoi caricare direttamente risorse DOM come immagini, caratteri e CSS dall'esterno del pacchetto di app Chrome.
Se vuoi mostrare un'immagine esterna nella tua app, devi richiederla tramite XMLHttpRequest,
trasformarla in un Blob e creare un ObjectURL. Puoi aggiungere questo ObjectURL
al DOM perché fa riferimento a un elemento in memoria nel contesto dell'app.
Mostra immagini in miniatura degli elementi attività
Cambiamo l'app in modo che cerchi gli URL immagine in un articolo di promemoria. Se l'URL ha l'aspetto di un'immagine (ad esempio, termina con .png, .jpg, .svg o .gif), applica la procedura descritta in precedenza per mostrare una miniatura dell'immagine accanto all'URL.
Aggiorna autorizzazioni
In un'app di Chrome, puoi effettuare chiamate XMLHttpRequest a qualsiasi URL, a condizione che ne specifichi il dominio nel manifest. Poiché non saprai in anticipo quale URL immagine verrà digitato dall'utente, chiedi l'autorizzazione per effettuare richieste a "<all_urls>"
.
In manifest.json, richiedi l'autorizzazione "
"permissions": ["storage", "alarms", "notifications",
"webview", "<all_urls>"],
Crea e cancella gli ObjectURL
In controller.js, aggiungi un metodo _createObjectURL()
per creare oggetti ObjectURL da un Blob:
Controller.prototype._createObjectURL = function(blob) {
var objURL = URL.createObjectURL(blob);
this.objectURLs = this.objectURLs || [];
this.objectURLs.push(objURL);
return objURL;
};
Gli oggetti ObjectURL contengono memoria, quindi quando non hai più bisogno di ObjectURL, devi revocarli. Aggiungi questo metodo _clearObjectURL()
a controller.js per gestire questa situazione:
Controller.prototype._clearObjectURL = function() {
if (this.objectURLs) {
this.objectURLs.forEach(function(objURL) {
URL.revokeObjectURL(objURL);
});
this.objectURLs = null;
}
};
Effettua una richiesta XHR
Aggiungi un metodo _requestRemoteImageAndAppend()
per eseguire una XMLHttpRequest sull'URL di un'immagine specifica:
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();
};
Al caricamento di XHR, questo metodo crea un ObjectURL
dalla risposta dell'XHR e aggiunge un elemento <img>
con questo ObjectURL
al DOM.
Analizza gli URL immagine negli elementi di promemoria
Ora aggiungi un metodo _parseForImageURLs()
che trovi tutti i link non ancora elaborati e li controlli per verificare la presenza di
immagini. Per ogni URL che sembra un'immagine, esegui _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]);
}
}
};
Visualizzare le miniature dell'elenco di cose da fare
Ora chiama _parseForImageURLs()
da showAll()
, showActive()
e 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));
};
Ripeti l'operazione per 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) {
...
}
Limita le dimensioni dell'immagine visualizzata
Infine, in _bowercomponents/todomvc-common/base.css, aggiungi una regola CSS per limitare le dimensioni dell'immagine:
.thumbnail img[data-src] {
max-width: 100px;
max-height: 28px;
}
Avvia l'app Attività completata
Completato il passaggio 5. Ricarica l'app e aggiungi un elemento di attività con un URL a un'immagine ospitata online. Alcuni URL che puoi utilizzare: http://goo.gl/nqHMF#.jpg o http://goo.gl/HPBGR#.png.
Per maggiori informazioni
Per informazioni più dettagliate su alcune delle API introdotte in questo passaggio, fai riferimento a:
Vuoi continuare con il passaggio successivo? Vai al Passaggio 6: esporta le cose da fare nel file system »