9

Sto eseguendo il porting di una delle mie estensioni di Firefox su Chrome e sto riscontrando un piccolo problema con una query AJAX. Il seguente codice funziona bene nell'estensione FF, ma non riesce con uno stato di "0" in Chrome.jQuery.ajax chiamata fallita all'interno dell'estensione Chrome

function IsImage(url) { 
    var isImage = false; 
    var reImageContentType = /image\/(jpeg|pjpeg|gif|png|bmp)/i; 
    var reLooksLikeImage = /\.(jpg|jpeg|gif|png|bmp)/i; 

    if(!reLooksLikeImage.test(url)) 
    { 
     return false; 
    } 

    var xhr = $.ajax({ 
     async: false, 
     type: "HEAD", 
     url: url, 
     timeout: 1000, 
     complete : function(xhr, status) { 
      switch(status) 
      { 
       case "success": 
        isImage = reImageContentType.test(xhr.getResponseHeader("Content-Type")); 
        break; 
      } 
     }, 
    }); 

    return isImage; 
} 

questa particolare parte del prolungamento controlla cosa c'è nella clipboard (un altro problema Chrome ho già risolto), e se si tratta di un collegamento ad un'immagine, si invia una richiesta HEAD e verifica la risposta "Content-Type" intestazione per essere sicuri che sia un'immagine. In tal caso, restituirà true incollando il testo degli appunti in un tag IMG. Altrimenti, se assomiglia ad un normale URL che non è un'immagine, lo avvolge in un tag A. Se non è un URL, fa semplicemente una semplice incolla.

In ogni caso, l'url da verificare è sicuramente un'immagine e funziona bene in FF, ma nella funzione completa, xhr.status è "0" e lo stato è "errore" quando la funzione viene completata. Aumentare il timeout a 10 secondi non aiuta. Ho verificato le immagini di prova dovrebbero tornare come "image/jpeg" durante l'esecuzione:

curl -i -X HEAD <imageURL> 

so anche che dovrebbe usare il successo e callback di errore invece di completo, ma non funzionano neanche. Qualche idea?

+0

Possa essere una restrizione di sicurezza su tutte le richieste AJAX di estensione? –

+0

non dovrebbe 'return isImage;' essere parte del callback completo? – pixeline

+0

@pixieline: Può essere. Quello era solo per avere un punto di ritorno, ma non arriva nemmeno lontano, perché lo switch (status) è "error", quindi quel ramo non viene mai chiamato. –

risposta

11

Come hai capito, Chris, in Content Scripts, non puoi fare alcun XHR tra domini. Dovresti eseguirli in una pagina di estensione come Sfondo, Popup o Opzioni per farlo.

Per ulteriori informazioni riguardanti la limitazione la trascrizione dei contenuti, si prega di fare riferimento a: http://code.google.com/chrome/extensions/content_scripts.html

E per ulteriori informazioni riguardanti la limitazione XHR, si prega di fare riferimento a: http://code.google.com/chrome/extensions/xhr.html

+6

Per chiunque incappi in questa pagina, questo è [non vero per Chrome 13+] (http://developer.chrome.com/extensions/whats_new.html#13) – Arithmomaniac

5

Controlla il file manifest. L'estensione ha il permesso di accedere a quell'URL?

Se aiuta al tuo secondo problema (o chiunque altro): è possibile inviare una richiesta di sfondo della pagina, come:

chrome.extension.sendRequest({var1: "var1value", var2: "value", etc}, 
function(response) { 
    //Do something once the request is done. 
}); 

La variabile response può essere tutto quello che vuoi che sia. Può semplicemente essere un successo o negare una stringa. Sta a te.

Su sfondo della pagina è possibile aggiungere un ascoltatore:

chrome.extension.onRequest.addListener(
function(request, sender, sendResponse) { 
     // Do something here 
     // Once done you can send back all the info via: 
     sendResponse(anything you want here); 

     // and it'll be passed back to your content script. 
}); 

Con questo si può passare la risposta dalla richiesta AJAX torna allo script contenuti e fare tutto ciò che si voleva fare con esso là.

+0

Quello era uno dei problemi. L'altro è che content_scripts non può inviare richieste AJAX. La pagina di sfondo può, tuttavia, che spiegherò nella mia risposta. –

5

Ho risolto parte del problema, in realtà la maggior parte. Innanzitutto, come Brennan e io abbiamo menzionato ieri, avevo bisogno di impostare i permessi in manifest.json.

"permissions": [ 
    "http://*/*", 
    "https://*/*" 
], 

non è l'ideale per concedere le autorizzazioni per ogni dominio, ma dal momento che le immagini possono essere ospitati da qualsiasi dominio, si dovrà fare, e dovrò evitare XSS.

L'altro problema è che Chrome effettivamente blocca qualsiasi cosa nella sezione content_scripts da effettuare chiamate AJAX, senza riuscire in silenzio. Tuttavia, non esiste tale restrizione sulla background_page, se ne hai uno. Quella pagina può fare tutte le chiamate AJAX che vuole e Chrome ha un'API per consentire allo script di aprire una porta e passare richieste a quella pagina di sfondo. Qualcuno ha scritto uno script chiamato XHRProxy come soluzione alternativa e l'ho modificato per ottenere l'intestazione di risposta appropriata. Funziona!

Il mio unico problema ora è capire come fare in modo che lo script attenda il risultato della chiamata da impostare nell'evento, invece di tornare immediatamente.

+0

Ehi, questo non regge più, gli script di contenuto ora possono fare richieste xml, vedere la mia risposta. –