onClick all’interno di Chrome Extension non funziona

Questa sembra essere la cosa più facile da fare, ma non funziona. In un normale browser i file .html e .js funzionano perfettamente, ma nell’estensione di Chrome la funzione onClick non sta eseguendo quello che dovrebbe fare.

file .js:

 function hellYeah(text) { document.getElementById("text-holder").innerHTML = text; } 

file .html:

     Getting Started Extension's Popup     
ha

hyhy

Quindi, fondamentalmente una volta che l’utente fa clic su “hyhy”, “ha” dovrebbe cambiare in “xxx”. E ancora: funziona perfettamente nel browser ma non funziona nell’estensione. Sai perché? Solo nel caso in cui sto allegando anche il manifest.json qui sotto.

Grazie in anticipo!

manifest.json:

 { "name": "My First Extension", "version": "1.0", "manifest_version": 2, "description": "The first extension that I made.", "browser_action": { "default_icon": "icon.png", "default_popup": "popup.html" }, "permissions": [ "http://api.flickr.com/" ] } 

Le estensioni di Chrome non ti consentono di avere JavaScript in linea ( documentazione ). Dovrai fare qualcosa di simile a questo.

Assegna un ID al collegamento ( diventa ) e utilizza addEventListener per associare l’evento. Inserisci quanto segue nel tuo file popup.js :

 document.addEventListener('DOMContentLoaded', function() { var link = document.getElementById('link'); // onClick's logic below: link.addEventListener('click', function() { hellYeah('xxx'); }); }); 

Ragionare

Questo non funziona, perché Chrome vieta qualsiasi tipo di codice in linea nelle estensioni tramite la politica di sicurezza dei contenuti.

JavaScript inline non verrà eseguito. Questa restrizione vieta sia i blocchi inline sia i gestori eventi in linea (ad esempio ).

Come rilevare

Se questo è davvero il problema, Chrome genera il seguente errore nella console:

Rifiutato di eseguire script inline perché viola la seguente direttiva di Content Security Policy: "script-src 'self' chrome-extension-resource:". È necessaria la parola chiave "non sicura", un hash ("sha256 -...") o un nonce ("nonce -...") per abilitare l'esecuzione in linea.

Per accedere alla console JavaScript di un popup (utile per il debug in generale), fai clic con il pulsante destro del mouse sul pulsante dell'estensione e seleziona "Ispeziona popup" dal menu di scelta rapida.

Ulteriori informazioni sul debug di un popup sono disponibili qui .

Come risolvere

È necessario rimuovere tutto il codice JavaScript incorporato. C'è una guida nella documentazione di Chrome .

Supponiamo che l'originale assomiglia a:

 Click this  

È necessario rimuovere l'attributo onclick e assegnare all'elemento un ID univoco:

 Click this  

E quindi albind il listener da uno script (che deve essere in un file .js , supponiamo popup.js ):

 // Pure JS: document.addEventListener('DOMContentLoaded', function() { document.getElementById("click-this").addEventListener("click", handler); }); // The handler also must go in a .js file function handler() { /* ... */ } 

Nota il wrapping in un evento DOMContentLoaded . Ciò garantisce che l'elemento esista al momento dell'esecuzione. Ora aggiungi il tag dello script, ad esempio nel del documento:

  

Alternativa se stai usando jQuery:

 // jQuery $(document).ready(function() { $("#click-this").click(handler); }); 

Rilassante la politica

D: L'errore indica i modi per consentire il codice in linea. Non voglio / non posso cambiare il mio codice, come posso abilitare gli script inline?

A: Nonostante quello che dice l'errore, non puoi abilitare lo script inline :

Non esiste alcun meccanismo per rilassare la limitazione contro l'esecuzione di JavaScript in linea. In particolare, l'impostazione di una politica di script che include 'unsafe-inline' avrà alcun effetto.

Aggiornamento: a partire da Chrome 46, è ansible inserire in whitelist blocchi di codice inline specifici:

A partire da Chrome 46, gli script inline possono essere inseriti nella whitelist specificando l'hash codificato in base64 del codice sorgente nel criterio. Questo hash deve essere preceduto dall'algoritmo di hash utilizzato (sha256, sha384 o sha512). Vedere l' utilizzo di hash per gli elementi per un esempio.

Tuttavia, non vedo prontamente un motivo per usarlo e non abiliterà attributi in linea come onclick="code" .

Ho avuto lo stesso problema e non volevo riscrivere il codice, quindi ho scritto una funzione per modificare il codice e creare gli eventi dichiarati in linea:

 function compile(qSel){ var matches = []; var match = null; var c = 0; var html = $(qSel).html(); var pattern = /(<(.*?)on([a-zA-Z]+)\s*=\s*('|")(.*)('|")(.*?))(>)/mg; while (match = pattern.exec(html)) { var arr = []; for (i in match) { if (!isNaN(i)) { arr.push(match[i]); } } matches.push(arr); } var items_with_events = []; var compiledHtml = html; for ( var i in matches ){ var item_with_event = { custom_id : "my_app_identifier_"+i, code : matches[i][5], on : matches[i][3], }; items_with_events.push(item_with_event); compiledHtml = compiledHtml.replace(/(<(.*?)on([a-zA-Z]+)\s*=\s*('|")(.*)('|")(.*?))(>)/m, "<$2 custom_id='"+item_with_event.custom_id+"' $7 $8"); } $(qSel).html(compiledHtml); for ( var i in items_with_events ){ $("[custom_id='"+items_with_events[i].custom_id+"']").bind(items_with_events[i].on, function(){ eval(items_with_events[i].code); }); } } $(document).ready(function(){ compile('#content'); }) 

Questo dovrebbe rimuovere tutti gli eventi in linea dal nodo selezionato e ricrearli invece con jquery.