如何在Google Chrome扩展程序中检测当前标签的mime类型?

时间:2011-02-07 12:17:31

标签: google-chrome google-chrome-extension mime-types mime

我想查看当前标签是否是背景页面中的PDF文件。

我可以在最后查看.pdf的网址,但是有一些PDF文件没有。

5 个答案:

答案 0 :(得分:12)

发布新请求只是为了获取MIME类型有点沉重,而且不可靠。例如,如果当前显示的页面是POST表单提交的结果,那么发出GET请求通常不会导致同一页面。

如果您正在开发经常需要访问此信息的扩展程序,请使用chrome.webRequest API跟踪回复。以下演示扩展程序在单击浏览器按钮时显示内容类型:

// 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 sniffing,除非设置了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",
        "*://*/*"
    ]
}

答案 1 :(得分:4)

您无法使用当前的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

答案 2 :(得分:1)

有些hackish方式(我不知道它是否总是有效或只是有时)是查看页面内容。在那里,您将找到chrome的PDF查看器元素。它看起来如下:

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

您可以检查&#34;输入&#34;属性以查看您正在处理的内容。

答案 3 :(得分:0)

我必须在我的某个扩展程序中执行类似的操作,并执行与@serg给出的the answer非常类似的操作,但使用的是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();
}

答案 4 :(得分:0)

您可以在当前标签上评估属性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标题(没有关于字符集的信息)。