Как определить тип пантомимы текущей вкладки в расширении Google Chrome? - PullRequest
13 голосов
/ 07 февраля 2011

Я хочу посмотреть, является ли текущая вкладка файлом PDF с фоновой страницы.

В конце я могу проверить URL для .pdf, но есть некоторые файлы PDF, у которых этого нет.

Ответы [ 5 ]

12 голосов
/ 10 января 2014

Выдача нового запроса только для получения типа MIME немного сложна и ненадежна. Например, если отображаемая в данный момент страница является результатом отправки формы POST, то запрос GET обычно не приводит к той же странице.

Если вы разрабатываете расширение, которому часто требуется доступ к этой информации, используйте API chrome.webRequest для отслеживания ответов. Следующее демо-расширение отображает тип контента после нажатия кнопки браузера:

// 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;
        }
    }
}

Примечания:

  • Это расширение показывает результат только для вкладок, которые загружены после расширение загружено.
  • Это работает только на страницах http / https. ftp :, file :, filesystem :, blob :, data: не поддерживается.
  • Когда сервер не указывает MIME-тип или когда MIME-тип равен text/plain, Chrome возвращается к MIME сниффинг , если не установлен X-Content-Type-Options: nosniff. В первом случае обнаруженный MIME-тип может быть любым. В последнем случае MIME-тип по умолчанию - text/plain.

Для полноты вот файл manifest.json, который можно использовать для проверки предыдущего кода:

{
    "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",
        "*://*/*"
    ]
}
4 голосов
/ 07 февраля 2011

Вы не можете получить его, используя текущий Chrome API afaik. Что вы можете сделать, это снова загрузить эту страницу через XHR и проверить возвращенный заголовок типа содержимого. Примерно так:

фон 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://*/*"
]

Для файлов PDF возвращаемый тип содержимого должен быть application/pdf. Однако следует иметь в виду, что заголовок типа содержимого также может содержать кодировку: text/html; charset=UTF-8.

1 голос
/ 21 ноября 2014

Несколько хакерский способ (я понятия не имею, работает ли он всегда или просто иногда) - смотреть на содержимое страницы. Там вы найдете элемент для просмотра PDF в Chrome. Это выглядит следующим образом:

<embed width="100%" height="100%" name="plugin" src="https://example.com/document.pdf" type="application/pdf">

Вы можете проверить этот атрибут "type", чтобы увидеть, с чем имеете дело.

0 голосов
/ 07 июня 2018

Вы можете оценить свойство document.contentType на текущей вкладке.Вот пример для browserAction:

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

Это свойство возвращает тип MIME, в котором отображается документ, а не заголовок Content-Type (нет информации о кодировке).

0 голосов
/ 06 августа 2015

Я должен был сделать нечто подобное в одном из моих расширений и сделал что-то очень похожее на ответ , данный @serg, но вместо этого используя запрос HEAD.Теоретически, HEAD-запрос должен быть идентичен GET-запросу, но без отправки тела ответа, которое в случае изображения или файла может быть довольно большим количеством дополнительных данных и времени ожидания.

Я также разделили сдвиньте заголовок, чтобы отбросить любые кодировки, которые могут быть добавлены к типу контента.

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();
}
...