Google chrome extension Chrome extension正在下载can';不总是指定文件扩展名吗?
我正在尝试创建一个Chrome扩展名,通过Chrome.downloads.download可以启动下载并指定生成的本地文件的文件名,特别是指定下载结果的文件扩展名 如果服务器为该文件播发内容类型为application/octet的流,则可以正常工作 但是,如果服务器播发某些其他内容类型(例如application/zip),则下载对象将设置为该MIME类型,并且下载的文件名将强制具有相关扩展名(例如“.zip”),而不是我指定的扩展名 我曾尝试使用onHeadersReceived更改传入标头中的内容类型,将其强制为application/octet流,但下载对象仍然具有原始MIME类型,并且文件扩展名仍然是强制的 使用chrome.downloads.OnDetermingFileName“建议”我所需的文件名+扩展名也无助于防止强制扩展。我已经禁用了所有其他扩展,还检查了onActionIgnored是否触发过(它没有)。最后,我为所有其他webRequest回调添加了日志记录,以查看是否有任何其他行为可以解释成功和失败案例之间的差异,但这个内容类型/mimetype问题似乎是罪魁祸首 这是一个在Linux(基本操作系统,Ubuntu的一个变种)上加载到Chrome84.0.4147.89的未打包扩展。我将在下面详细介绍扩展代码,但我认为可能只是关于如何创建下载对象的流程,这是a)不可能做到的,或者b)意味着我需要以其他方式做到这一点 谢谢你的帮助 以下是我的测试扩展的清单:Google chrome extension Chrome extension正在下载can';不总是指定文件扩展名吗?,google-chrome-extension,Google Chrome Extension,我正在尝试创建一个Chrome扩展名,通过Chrome.downloads.download可以启动下载并指定生成的本地文件的文件名,特别是指定下载结果的文件扩展名 如果服务器为该文件播发内容类型为application/octet的流,则可以正常工作 但是,如果服务器播发某些其他内容类型(例如application/zip),则下载对象将设置为该MIME类型,并且下载的文件名将强制具有相关扩展名(例如“.zip”),而不是我指定的扩展名 我曾尝试使用onHeadersReceived更改传入标
{
"name": "Test DL Rename",
"version": "1.0",
"manifest_version": 2,
"description": "Add a file extension to the name of a download.",
"background": {
"scripts": ["background.js"],
"persistent": true
},
"permissions": [
"contextMenus",
"downloads",
"webRequest",
"webRequestBlocking",
"<all_urls>"
]
}
{
“名称”:“测试DL重命名”,
“版本”:“1.0”,
“清单版本”:2,
“说明”:“将文件扩展名添加到下载的名称中。”,
“背景”:{
“脚本”:[“background.js”],
“持久”:正确
},
“权限”:[
“上下文菜单”,
“下载”,
“网络请求”,
“webRequestBlocking”,
"
看起来像是Chrome处理下载的一个有意的限制,以确保“安全”,你可以通过宣传你的用例来竞争
同时,自己下载blob并更改其类型:
chrome.contextMenus.onClicked.addListener(异步({linkUrl:url})=>{
const blob=await(await-fetch(url)).blob();
const typedBlob=blob.type===“应用程序/八位字节流”?blob:
新Blob([Blob],{type:'application/octet stream'});
chrome.downloads.download({
url:url.createObjectURL(typedBlob),
文件名:url.substring(url.lastIndexOf('/')+1)+'.qz',
冲突行为:“不公平”,
});
});
另外,现在您不需要webRequest API,您可以在manifest.json中使用“persistent”:false
(FWIW有一种方法可以通过将webRequest
放入可选的\u权限中,同时使用这两种权限,请参见)
const CONTEXT_MENU_ID = "TEST_DL_RENAME";
// add our thing to the context menu for links
chrome.contextMenus.create(
{
id: CONTEXT_MENU_ID,
title: "Test DL Rename",
contexts: ["link"]
}
);
// test download-renaming by adding ".qz" extension to downloaded file
chrome.contextMenus.onClicked.addListener(
function(info, tab) {
if (info.menuItemId !== CONTEXT_MENU_ID) {
return;
}
filename = info.linkUrl.substring(info.linkUrl.lastIndexOf('/') + 1);
qzFilename = filename + ".qz";
console.log("specifying name for download: " + qzFilename);
chrome.downloads.download(
{
url: info.linkUrl,
filename: qzFilename,
conflictAction: "uniquify"
},
function(downloadId) {
console.log("started download ID " + downloadId);
}
);
}
);
// test setting content-type on a received download
chrome.webRequest.onHeadersReceived.addListener(
function(details) {
// if doing this for real, we'd track which URLs we actually want to change
// for now just change anything that is a zipfile
if (details.url.split('.').pop() != "zip") {
return {};
}
for (var i = 0; i < details.responseHeaders.length; i++) {
if (details.responseHeaders[i].name.toLowerCase() == "content-type"){
console.log("forcing content-type to application/octet-stream");
details.responseHeaders[i].value = "application/octet-stream";
break;
}
}
return {
responseHeaders: details.responseHeaders
};
},
{
urls: ["<all_urls>"]
},
["blocking", "responseHeaders"]
);