Jak mogę pobrać plik za pomocą window.aport?

Jeśli chcę pobrać plik, co powinienem zrobić w bloku then poniżej?

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

Uwaga kody są po stronie klienta.

Author: Mariusz Pawelski, 2015-09-13

8 answers

EDIT : odpowiedź syg jest lepsza. Wystarczy użyć biblioteki downloadjs .

Odpowiedź, którą podałem działa dobrze na Chrome, ale na Firefoksie i IE potrzebujesz innego wariantu tego kodu. Lepiej do tego użyć biblioteki.


Miałem podobny problem (trzeba przekazać nagłówek autoryzacji, aby pobrać plik, więc To rozwiązanie nie pomogło).

Ale na podstawie tej odpowiedzi możesz użyć createObjectURL, aby przeglądarka zapisała plik pobrany przez 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         
        });
    });
 77
Author: Mariusz Pawelski,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-10-05 13:08:09

Jest to krótsze i wydajniejsze, brak bibliotek tylko API fetch

const url ='http://sample.example.file.doc'
const authHeader ="Bearer 6Q************" 

const options = {
  headers: {
    Authorization: authHeader
  }
};
 fetch(url, options)
  .then( res => res.blob() )
  .then( blob => {
    var file = window.URL.createObjectURL(blob);
    window.location.assign(file);
  });
 53
Author: Lucas Matos,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-01-28 00:04:25

Tymczasowo rozwiązuję ten problem używając download.js i 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);
  });
}

To działa dla małych plików, ale może nie działa dla dużych plików. Myślę, że powinienem wykopać Strumień więcej.

 49
Author: zachguo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-15 23:42:45

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

Lub:

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");
 11
Author: Zibri,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-03-17 11:01:44

Używanie dowloadjs. Spowoduje to przetworzenie nazwy pliku z nagłówka.

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");
    });
};
 8
Author: Daniel,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-05-03 00:06:02

Oto przykład użycia node-fetch dla każdego, kto to znajdzie.

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
Author: Michael Hobbs,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-07-15 10:33:40

Próbowałem window.fetch, ale okazało się to skomplikowane z moją aplikacją REACTOWĄ

Teraz tylko zmieniam okno.miejsce.href i dodaj paramy zapytań, takie jak jsonwebtoken i 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)

Wyniki końcowe są naprawdę ładne, okno sprawia, że żądanie i pobiera plik, a przełącznik zdarzeń nie przenosi strony, jej tak, jakby wywołanie window.location.href było jak wywołanie lowkey fetch().

 1
Author: Maddocks,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2019-08-26 14:51:59

Zgodnie z niektórymi innymi odpowiedziami, zdecydowanie możesz użyć window.Pobierz i Pobierz.js aby pobrać plik. Jednak przy użyciu window.fetch with blob ma ograniczenia dotyczące pamięci nałożone przez przeglądarkę i pobieranie.js ma również swoje ograniczenia kompatybilności .

Jeśli chcesz pobrać duży plik, nie chcesz go umieszczać w pamięci po stronie klienta, aby podkreślić przeglądarkę, prawda? Zamiast tego prawdopodobnie wolisz pobrać go za pośrednictwem strumienia. W takim przypadek, użycie linku HTML do pobrania pliku jest jednym z najlepszych / najprostszych sposobów, szczególnie w przypadku pobierania dużych plików za pośrednictwem strumienia.

Krok pierwszy: Utwórz i stylizuj element łącza

Możesz sprawić, że link będzie niewidoczny, ale nadal będzie możliwy do zaskarżenia.

HTML:

<a href="#" class="download-link" download>Download</a>

CSS:

.download-link {
  position: absolute;
  top: -9999px;
  left: -9999px;
  opacity: 0;
}

Krok drugi: Ustaw href łącza i uruchom Zdarzenie click

JavaScript

let url = `https://www.googleapis.com/drive/v2/files/${fileId}?alt=media`;

const downloadLink = document.querySelector('.download-link')
downloadLink.href = url + '&ts=' + new Date().getTime() // Prevent cache
downloadLink.click()

Uwagi:

  • możesz dynamicznie w razie potrzeby Wygeneruj element łącza.
  • [34]} to podejście jest szczególnie przydatne do pobierania, poprzez strumień, dużych plików, które są dynamicznie generowane po stronie serwera{[35]]}
 1
Author: Yuci,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2020-12-16 23:08:17