web-dev-qa-db-ja.com

window.fetchを使用してファイルをダウンロードするにはどうすればよいですか?

ファイルをダウンロードしたい場合、以下のthenブロックで何をすべきですか?

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(...);
}

コードはクライアント側にあることに注意してください。

32
syg

download.js および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);
  });
}

小さなファイルでは機能しますが、大きなファイルでは機能しない可能性があります。掘る必要があると思います Stream more。

32
syg

[〜#〜] edit [〜#〜]:sygの回答が優れています。 downloadjs ライブラリを使用するだけです。

私が提供した答えはChromeではうまくいきますが、FirefoxではIEこのコードの異なるバリアントが必要です。そのためにはライブラリを使用する方が良いです。


同様の問題がありました(ファイルをダウンロードするために認証ヘッダーを渡す必要があるため、 this ソリューションは役に立たなかった)。

しかし、 this answerに基づいて、createObjectURLを使用して、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

これを見つけた人のためにnode-fetchを使用する例を次に示します。

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

Dowloadjsを使用します。これにより、ヘッダーのファイル名が解析されます。

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");

または:

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