Come posso rilevare il tipo di mimo della scheda corrente in un’estensione Google Chrome?

Voglio vedere se la scheda corrente è un file PDF da una pagina di sfondo.

Posso controllare l’url per .pdf alla fine ma ci sono alcuni file PDF che non hanno questo.

Non puoi ottenerlo utilizzando l’afAk dell’API di Chrome corrente. Quello che puoi fare è caricare di nuovo questa pagina tramite XHR e controllare l’intestazione del tipo di contenuto restituito. Qualcosa come questo:

background html:

chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) { if(changeInfo.status == "loading") { if(checkIfUrlHasPdfExtension(tab.url)) { //.pdf pdfDetected(tab); } else { var xhr = new XMLHttpRequest(); xhr.open("GET", tab.url, true); xhr.onreadystatechange = function() { if (xhr.readyState == 4) { var contentType = xhr.getResponseHeader("Content-Type"); if(checkIfContentTypeIsPdf(contentType)) { pdfDetected(tab); } } } xhr.send(); } } }); 

manifest.json:

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

Per i file PDF il tipo di contenuto restituito deve essere application/pdf . Qualcosa da tenere a mente però è che l’intestazione content-type potrebbe contenere anche la codifica: text/html; charset=UTF-8 text/html; charset=UTF-8 .

L’emissione di una nuova richiesta solo per ottenere il tipo MIME è un po ‘pesante e non affidabile. Ad esempio, se la pagina attualmente visualizzata è il risultato di un invio di moduli POST, l’invio di una richiesta GET solito non porta alla stessa pagina.

Se stai sviluppando un’estensione che richiede spesso l’accesso a queste informazioni, utilizza l’API chrome.webRequest per tenere traccia delle risposte. La seguente estensione demo mostra il tipo di contenuto al clic del pulsante del browser:

 // background.js var tabToMimeType = {}; chrome.webRequest.onHeadersReceived.addListener(function(details) { if (details.tabId !== -1) { var header = getHeaderFromHeaders(details.responseHeaders, 'content-type'); // If the header is set, use its value. Otherwise, use undefined. tabToMimeType[details.tabId] = header && header.value.split(';', 1)[0]; } }, { urls: ['*://*/*'], types: ['main_frame'] }, ['responseHeaders']); chrome.browserAction.onClicked.addListener(function(tab) { alert('Tab with URL ' + tab.url + ' has MIME-type ' + tabToMimeType[tab.id]); }); function getHeaderFromHeaders(headers, headerName) { for (var i = 0; i < headers.length; ++i) { var header = headers[i]; if (header.name.toLowerCase() === headerName) { return header; } } } 

Gli appunti:

  • Questa estensione mostra solo il risultato per le tabs che vengono caricate dopo che l'estensione è stata caricata.
  • Funziona solo su pagine http / https. ftp :, file :, filesystem :, blob :, data: non è supportato.
  • Quando nessun tipo MIME viene specificato dal server o quando il tipo MIME è text/plain , Chrome torna a eseguire lo sniffing MIME a meno che non sia impostato X-Content-Type-Options: nosniff . Nel primo caso, il tipo MIME rilevato potrebbe essere qualsiasi cosa. In quest'ultimo caso, il tipo MIME predefinito è text/plain .

Per completezza, ecco un file manifest.json che può essere utilizzato per testare il codice precedente:

 { "name": "Click button to see MIME", "version": "1", "manifest_version": 2, "background": { "scripts": ["background.js"], "persistent": true }, "browser_action": { "default_title": "Show MIME" }, "permissions": [ "webRequest", "activeTab", "*://*/*" ] } 

Un modo un po ‘hacker (non ho idea se funzioni sempre o solo qualche volta) è guardare il contenuto della pagina. Lì troverai un elemento per il visualizzatore PDF di Chrome. Guarda lungo queste linee:

  

Puoi controllare l’attributo “tipo” per vedere con cosa hai a che fare.

Ho dovuto fare qualcosa di simile in una delle mie estensioni e ho fatto qualcosa di molto simile alla risposta data da @serg ma usando invece una richiesta HEAD. In teoria, una richiesta HEAD dovrebbe essere identica a una richiesta GET ma senza inviare il corpo della risposta, che nel caso di un’immagine o di un file potrebbe essere un bel po ‘di dati extra e di tempo in attesa.

Ho anche diviso e spostato l’intestazione per eliminare tutti i set di caratteri che potrebbero essere aggiunti al tipo di contenuto.

 getContentType: function(tab, callback){ var xhr = new XMLHttpRequest(); xhr.open("HEAD", tab.url, false); xhr.onload = function(e) { if (xhr.readyState === 4) { if(xhr.status === 200) { callback(xhr.getResponseHeader("Content-Type").split(";").shift()); } else{ callback('Unknown'); console.error(xhr.statusText); return; } } }; xhr.onerror = function (e) { console.error(xhr.statusText); return; }; xhr.send(); } 

È ansible valutare la proprietà document.contentType nella scheda corrente. Ecco un esempio su browserAction :

 chrome.browserAction.onClicked.addListener(() => { chrome.tabs.getSelected((tab) => { chrome.tabs.executeScript(tab.id, { code: 'document.contentType' }, ([ mimeType ]) => { alert(mimeType); }); }) }); 

Questa proprietà restituisce il tipo MIME in cui viene eseguito il rendering del documento, non l’intestazione Content-Type (nessuna informazione sul set di caratteri).