Google chrome 如何检测当前选项卡';Google Chrome扩展中的mime类型是什么?

Google chrome 如何检测当前选项卡';Google Chrome扩展中的mime类型是什么?,google-chrome,google-chrome-extension,mime-types,mime,Google Chrome,Google Chrome Extension,Mime Types,Mime,我想看看当前选项卡是否是来自背景页的PDF文件 我可以在最后查看.pdf的url,但有些pdf文件没有该文件。使用当前的Chrome API afaik无法获取该文件。您可以做的是再次通过加载此页面并检查返回的内容类型标题。大概是这样的: 背景html: chrome.tabs.onUpdated.addListener(function(tabId, changeInfo, tab) { if(changeInfo.status == "loading") { if(c

我想看看当前选项卡是否是来自背景页的PDF文件


我可以在最后查看.pdf的url,但有些pdf文件没有该文件。

使用当前的Chrome API afaik无法获取该文件。您可以做的是再次通过加载此页面并检查返回的内容类型标题。大概是这样的:

背景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();
        }
    }
});
"permissions": [
    "tabs", "http://*/*", "https://*/*"
]
manifest.json:

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();
        }
    }
});
"permissions": [
    "tabs", "http://*/*", "https://*/*"
]

对于PDF文件,返回的内容类型应为
application/PDF
。但需要记住的是,内容类型头也可以包含编码:
text/html;charset=UTF-8

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

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

//background.js
var tabToMimeType={};
chrome.webRequest.onHeadersReceived.addListener(函数(细节){
如果(details.tabId!=-1){
var header=getHeaderFromHeaders(details.responseHeaders,“内容类型”);
//如果设置了标题,请使用其值。否则,请使用未定义。
tabToMimeType[details.tabId]=header&&header.value.split(“;”,1)[0];
}
}, {
URL:['*://*/*'],
类型:[“主框架”]
},[“负责人]);
chrome.browserAction.onClicked.addListener(函数(选项卡){
警报('URL为'+Tab.URL+'的选项卡具有MIME类型'+tabToMimeType[Tab.id]);
});
函数getHeaderFromHeaders(headers,headerName){
对于(变量i=0;i
注:

  • 此扩展仅显示加载扩展后加载的选项卡的结果
  • 这仅适用于http/https页面。不支持ftp:、文件:、文件系统:、blob:、数据
  • 当服务器未指定MIME类型或MIME类型为
    text/plain
    时,除非设置了
    X-Content-type-Options:nosniff
    ,否则Chrome会返回到。在第一种情况下,检测到的MIME类型可以是任何类型。在后一种情况下,默认MIME类型是
    text/plain
为了完整起见,这里有一个
manifest.json
文件,可用于测试前面的代码:

{
“名称”:“单击按钮查看MIME”,
“版本”:“1”,
“清单版本”:2,
“背景”:{
“脚本”:[“background.js”],
“持久”:正确
},
“浏览器操作”:{
“默认标题”:“显示MIME”
},
“权限”:[
“网络请求”,
“活动标签”,
"*://*/*"
]
}
一种有点粗俗的方式(我不知道它是一直有效还是有时有效)是查看页面内容。在那里你会发现chrome的PDF查看器的一个元素。它看起来是这样的:

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


您可以检查“type”属性以查看您正在处理的内容。

我必须在我的一个扩展中执行类似的操作,并且执行了与@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();
}

您可以在当前选项卡上计算属性
document.contentType
。 下面是一个有关
浏览操作的示例:


此属性返回文档呈现为的MIME类型,而不是
内容类型
标题(没有有关字符集的信息)。

谢谢,我相信这会起作用。但我恐怕不会使用它,因为每个页面都会被加载两次。@orn我同意,我只会检查pdf扩展,应该足以满足99%的情况我正在搜索类似的内容,因为我只会在打开扩展弹出窗口时使用它,我想(希望)请求在大多数情况下将使用缓存页面。@serg如何将类型传播到
manifest.js
中的
content\u脚本
-文件?您是否开发过具有此功能的扩展?我很想有这样一个扩展,但我不想学习如何为一些个人用途编写一个。你的回答非常详细和有用。谢谢真的很有帮助。这比公认的答案要好得多-实际上不应该有任何扩展重新请求标题。回答不错,但不幸的是webRequest需要设置
“persistent”:true,这会阻止使用现在首选的事件页面。事件页面的等效API declarativeWebRequest仍处于测试阶段,实际上在这一点上似乎完全处于搁置状态。这真的帮了我的忙,非常感谢!这确实有点骇人听闻,但这似乎是对“file://”URL也有效的唯一方法(前提是manifest.json声明注入的脚本应该进入与“file://*”选择器匹配的URL)。以下是我在注入脚本中使用的代码:
if(document.body.childElementCount==1){var embed=document.body.firstElementChild;if(embed.tagName==“embed”&&embed.getAttribute(“type”)==“application/pdf”){/*做点什么*/}