Empresas
Empleos
  • Sobre nosotros
  • Soluciones
    • Publicación de vacantes
      Publica tu vacante y recibe candidatos calificados en 48h.
    • Evaluación de candidatos
      500+ pruebas técnicas y psicológicas, más anti-fraude.
    • Headhunting
      Búsqueda ejecutiva a la medida de principio a fin.
    • Nómina + EOR
      Dispersión de nómina y EOR en más de 15 países de LATAM.
  • Precios
  • Empleos

0

228
Vistas
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 Respuestas
Responde la pregunta

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 Denunciar
Responde la pregunta
Encuentra empleos remotos

¡Descubre la nueva forma de encontrar empleo!

Top de empleos
Top categorías de empleo
Empresas
Publicar vacante Precios Comercial
Legal
Términos y condiciones Política de privacidad
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Recomiéndame algunas ofertas
Necesito ayuda