Empresas
Empregos
  • Sobre nós
  • Soluções
    • Publicação de vagas
      Publique sua vaga e receba candidatos qualificados em 48h.
    • Avaliações de candidatos
      Mais de 500 testes técnicos e psicológicos, mais anti-fraude.
    • Headhunting
      Busca executiva personalizada do início ao fim.
    • Folha de Pagamento + EOR
      Dispersão de folha e EOR em mais de 15 países da LATAM.
  • Preços
  • Empregos

0

225
Visualizações
Transfer response from remote server to content script (Chrome extension)

What I want to achieve: Upon clicking icon of my Chrome extension, a file with downloaded from remote location and the user is presented with saveAs dialog.

Caveats: I'm using latest manifest from Google, namely v3.

I have edited this post many times as I I was able to achieve more and more. I leave only my latest code.

tl;dr Now almost everything works.Crucial thing is missing: response from server (body) is not saved. Instead string [object Object] is saved.

// 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);
}
about 4 years ago · Juan Pablo Isaza
1 Respostas
Responde à pergunta

0

The problem is in serializing the blob object from the chrome extension to the content script, which I think it's a bug in chrome. if you try to log the blob object that saveFile() receives, you will notice it's an empty object.

So instead of passing the blob object, you have to pass another serializable object to the content script.

I have converted the blob object to a base64 object then passed it to the content script.

First, let's create a function to convert the blob object to a base64 object

function blobToBase64(blob) {
    return new Promise((resolve, _) => {
        const reader = new FileReader();
        reader.onloadend = () => resolve(reader.result);
        reader.readAsDataURL(blob);
    });
}

Then convert the blob object

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],
    }));
  }
});

then in the saveFile() method, you need to convert that base64 into a file

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.

about 4 years ago · Juan Pablo Isaza Relatório
Responde à pergunta
Encontrar trabalhos remotos

Descubra a nova forma de encontrar um emprego!

melhores empregos
Principais categorias de trabalho
Empresas
Postar vaga Preços Comercial
Jurídico
Termos e Condições Política de privacidade
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomende algumas ofertas para mim
Preciso de ajuda