我想要實作的目標:單擊 Chrome 擴展程式的圖示后,從遠程位置下載的檔案和用戶將顯示另存為對話框。
注意事項:我使用的是 Google 的最新清單,即v3.
我已經多次編輯這篇文章,因為 II 能夠實作越來越多的目標。我只留下我最新的代碼。
tl;dr現在幾乎一切正常。缺少重要的事情:來自服務器(主體)的回應未保存。而是[object Object]保存字串。
// when icon is clicked
chrome.action.onClicked.addListener(tab => {
if (tab.url.startsWith('http')) {
post({url: tab.url})
.then(async res => ({
filename: getFilename(res.headers.get('Content-Disposition')),
blob: await res.blob()
}))
.then(response => {
console.log(response);
chrome.scripting.executeScript({
target: {tabId: tab.id},
func: saveFile,
args: [response.filename, response.blob],
})
})
.catch((error) => chrome.scripting.executeScript({
target: {tabId: tab.id},
func: showAlert,
args: [error],
}));
}
});
function getFilename(header) {
return /filename="(. )"/.exec(header)[1];
}
async function post(data = {}) {
return await fetch('http://localhost:5000/citation',{
method: 'POST',
body: new URLSearchParams(data)
});
}
function showAlert(error) {
let message = error.error !== null ? error.error : error.message;
alert("Error: " message);
}
async function saveFile(filename, blob) {
let link = document.createElement('a');
let url = window.URL.createObjectURL(new Blob([blob],
{type: 'application/octet-stream'}));
link.href = url;
link.download = filename;
link.click();
// For Firefox it is necessary to delay revoking the ObjectURL.
setTimeout(() => {
window.URL.revokeObjectURL(url);
}, 250);
}
uj5u.com熱心網友回復:
問題在于將blob物件從 chrome 擴展名序列化到內容腳本,我認為這是 chrome 中的一個錯誤。如果您嘗試記錄saveFile()接收到的 blob 物件,您會注意到它是一個空物件。
因此blob,您必須將另一個可序列化的物件傳遞給內容腳本,而不是傳遞物件。
我已將blob物件轉換為物件,base64然后將其傳遞給內容腳本。
首先,讓我們創建一個函式來將blob物件轉換為base64物件
function blobToBase64(blob) {
return new Promise((resolve, _) => {
const reader = new FileReader();
reader.onloadend = () => resolve(reader.result);
reader.readAsDataURL(blob);
});
}
然后轉換blob物件
chrome.action.onClicked.addListener(tab => {
if (tab.url.startsWith('http')) {
post({url: tab.url})
.then(async res => ({
filename: getFilename(res.headers.get('Content-Disposition')),
blob: await res.blob()
}))
.then(async response => {
var base64 = await blobToBase64(response.blob)
chrome.scripting.executeScript({
target: {tabId: tab.id},
func: saveFile,
args: [response.filename, base64],
})
})
.catch((error) => chrome.scripting.executeScript({
target: {tabId: tab.id},
func: showAlert,
args: [error],
}));
}
});
然后在saveFile()方法中,您需要將其base64轉換為檔案
async function saveFile(filename, base64URL) {
fetch(base64URL)
.then(res => res.blob())
.then(blob => {
let link = document.createElement('a');
let url = window.URL.createObjectURL(new Blob([blob],
{ type: 'application/octet-stream' }));
link.href = url;
link.download = filename;
link.click();
// For Firefox it is necessary to delay revoking the ObjectURL.
setTimeout(() => {
window.URL.revokeObjectURL(url);
}, 250);
})
}
If you will not do anything in saveFile() but download the file, then it will be better to download the file from the extension itself because converting the blob to base64 then getting it back to blob again is slowing down the downloading process.
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/354289.html
