Я хочу посмотреть, будет ли текущая вкладка PDF файлом с фоновой страницы.
Я могу проверить url для .pdf в конце, но есть некоторые файлы PDF, которые этого не имеют.
Я хочу посмотреть, будет ли текущая вкладка PDF файлом с фоновой страницы.
Я могу проверить url для .pdf в конце, но есть некоторые файлы PDF, которые этого не имеют.
Вы не можете получить его, используя текущий API-интерфейс Chrome API. Вы можете снова загрузить эту страницу через XHR и проверить возвращенный заголовок типа содержимого. Что-то вроде этого:
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://*/*"
]
Для возвращаемых файлов PDF тип содержимого должен быть application/pdf
. Что-то, о чем следует помнить, состоит в том, что заголовок содержимого также может содержать кодировку: text/html; charset=UTF-8
.
Выдача нового запроса только для получения типа 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;
}
}
}
Примечания:
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",
"*://*/*"
]
}
Несколько хакерский способ (я понятия не имею, работает ли он всегда или просто иногда), чтобы посмотреть содержимое страницы. Там вы найдете элемент для просмотра 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();
}