web-dev-qa-db-fra.com

Comment puis-je télécharger un fichier en utilisant window.fetch?

Si je veux télécharger un fichier, que dois-je faire dans le bloc then ci-dessous?

function downloadFile(token, fileId) {
  let url = `https://www.googleapis.com/drive/v2/files/${fileId}?alt=media`;
  return fetch(url, {
    method: 'GET',
    headers: {
      'Authorization': token
    }
  }).then(...);
}

Notez que les codes sont dans le côté client.

32
syg

Je résous temporairement ce problème en utilisant download.js et blob.

let download = require('./download.min');

...

function downloadFile(token, fileId) {
  let url = `https://www.googleapis.com/drive/v2/files/${fileId}?alt=media`;
  return fetch(url, {
    method: 'GET',
    headers: {
      'Authorization': token
    }
  }).then(function(resp) {
    return resp.blob();
  }).then(function(blob) {
    download(blob);
  });
}

Cela fonctionne pour les petits fichiers, mais peut-être pas pour les gros fichiers. Je pense que je devrais creuser Stream plus.

32
syg

[~ # ~] éditer [~ # ~] : syg réponse est préférable. Il suffit d'utiliser downloadjs library.

La réponse que j'ai fournie fonctionne bien sur Chrome, mais sur Firefox et IE vous avez besoin de différentes variantes de ce code. Il est préférable d'utiliser la bibliothèque pour cela.


J'ai eu un problème similaire (besoin de passer l'en-tête d'autorisation pour télécharger un fichier donc this la solution n'a pas aidé).

Mais en fonction de this , vous pouvez utiliser createObjectURL pour que le navigateur enregistre un fichier téléchargé par Fetch API.

getAuthToken()
    .then(token => {
        fetch("http://example.com/ExportExcel", {
            method: 'GET',
            headers: new Headers({
                "Authorization": "Bearer " + token
            })
        })
        .then(response => response.blob())
        .then(blob => {
            var url = window.URL.createObjectURL(blob);
            var a = document.createElement('a');
            a.href = url;
            a.download = "filename.xlsx";
            document.body.appendChild(a); // we need to append the element to the dom -> otherwise it will not work in firefox
            a.click();    
            a.remove();  //afterwards we remove the element again         
        });
    });
34
Mariusz Pawelski

Voici un exemple d'utilisation de node-fetch pour tous ceux qui le trouvent.

reportRunner({url, params = {}}) {
    let urlWithParams = `${url}?`
    Object.keys(params).forEach((key) => urlWithParams += `&${key}=${params[key]}`)
    return fetch(urlWithParams)
        .then(async res => ({
            filename: res.headers.get('content-disposition').split('filename=')[1],
            blob: await res.blob()
        }))
        .catch(this.handleError)
}
3
Michael Hobbs

Utilisation de dowloadjs. Cela analysera le nom de fichier à partir de l'en-tête.

fetch("yourURL", {
    method: "POST",
    body: JSON.stringify(search),
    headers: {
        "Content-Type": "application/json; charset=utf-8"
    }
    })
    .then(response => {
        if (response.status === 200) {
            filename = response.headers.get("content-disposition");
            filename = filename.match(/(?<=")(?:\\.|[^"\\])*(?=")/)[0];
            return response.blob();
        } else {
        return;
        }
    })
    .then(body => {
        download(body, filename, "application/octet-stream");
    });
};
2
Daniel
function download(dataurl, filename) {
  var a = document.createElement("a");
  a.href = dataurl;
  a.setAttribute("download", filename);
  a.click();
  return false;
}

download("data:text/html,HelloWorld!", "helloWorld.txt");

ou:

function download(url, filename) {
fetch(url).then(function(t) {
    return t.blob().then((b)=>{
        var a = document.createElement("a");
        a.href = URL.createObjectURL(b);
        a.setAttribute("download", filename);
        a.click();
    }
    );
});
}

download("https://get.geojs.io/v1/ip/geo.json","geoip.json")
download("data:text/html,HelloWorld!", "helloWorld.txt");
1
Zibri

J'ai essayé window.fetch mais cela a fini par être compliqué avec mon application REACT

maintenant, je viens de changer window.location.href et d'ajouter des paramètres de requête comme le jsonwebtoken et le other stuff.


///==== client side code =====
var url = new URL(`http://${process.env.REACT_APP_URL}/api/mix-sheets/list`);
url.searchParams.append("interval",data.interval);
url.searchParams.append("jwt",token)

window.location.href=url;

// ===== server side code =====

// on the server i set the content disposition to a file
var list = encodeToCsv(dataToEncode);
res.set({"Content-Disposition":`attachment; filename=\"FileName.csv\"`});
res.status(200).send(list)

le résultat final finit par être plutôt joli, la fenêtre demande et télécharge le fichier et ne change pas d’événement, déplacez la page, c'est comme si l'appel window.location.href ressemblait à une lowkey fetch() appel.

0
Maddocks