In questo passaggio, scoprirai:
- 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'uso delle risorse esterne
La piattaforma per le app di Chrome impone alla tua app di essere pienamente conforme ai criteri di sicurezza del contenuto (CSP). Non puoi caricare direttamente risorse DOM come immagini, caratteri e CSS dall'esterno dell'app Chrome pacchetto.
Se vuoi mostrare un'immagine esterna nella tua app, devi richiederla tramite XMLHttpRequest,
trasformarlo in un Blob e creare un ObjectURL. Questo ObjectURL
può essere aggiunto al
DOM perché fa riferimento a un elemento in memoria nel contesto dell'app.
Mostra le immagini in miniatura delle attività da svolgere
Cambiamo la nostra app in modo che cerchi gli URL immagine in una voce di promemoria. Se l'URL assomiglia a un'immagine (ad esempio, termina con .png, .jpg, .svg o .gif), applica la procedura descritta in precedenza per mostrare immagine miniatura accanto all'URL.
Aggiorna autorizzazioni
In un'app di Chrome, puoi effettuare chiamate XMLHttpRequest a qualsiasi URL, purché specifichi il dominio in
del file manifest. Dato che non saprai in anticipo quale URL dell'immagine digiterà l'utente, chiedi l'autorizzazione
invia richieste a "<all_urls>"
.
In manifest.json, richiedi il "
"permissions": ["storage", "alarms", "notifications",
"webview", "<all_urls>"],
Crea e cancella gli oggetti 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 URL oggetto conservano la memoria, quindi quando non hai più bisogno dell'URL dell'oggetto, devi revocarlo. Aggiungi questo
_clearObjectURL()
a controller.js per gestirlo:
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 su un determinato URL immagine:
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 delle immagini nelle cose da fare
Ora aggiungi un metodo _parseForImageURLs()
che trovi tutti i link non ancora elaborati e li controlli
in formato Docker. Per ogni URL simile a 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 nell'elenco delle 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));
};
Fai lo stesso 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 della immagine:
.thumbnail img[data-src] {
max-width: 100px;
max-height: 28px;
}
Lancia l'app delle cose da fare completata
Hai completato il passaggio 5. Ricarica la tua app e aggiungi una voce di attività con un URL a un'immagine ospitata online. Alcune 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 andare al passaggio successivo? Vai al Passaggio 6: esporta le cose da fare nel file system »