Pobieranie plików (przy użyciu Axios i Security)
Jest to jeszcze bardziej skomplikowane, gdy chcesz pobierać pliki za pomocą Axios i niektórych środków bezpieczeństwa. Aby nikt inny nie spędzał zbyt wiele czasu na rozwiązywaniu tego, pozwól, że przeprowadzę cię przez to.
Musisz zrobić 3 rzeczy:
1. Configure your server to permit the browser to see required HTTP headers
2. Implement the server-side service, and making it advertise the correct file type for the downloaded file.
3. Implementing an Axios handler to trigger a FileDownload dialog within the browser
Te kroki są w większości wykonalne - ale są znacznie skomplikowane ze względu na relację przeglądarki do CORS. Krok po kroku:
1. Skonfiguruj serwer (HTTP)
Stosując zabezpieczenia transportu, JavaScript wykonywany w przeglądarce może [zgodnie z projektem] uzyskać dostęp tylko do 6 nagłówków HTTP faktycznie wysłanych przez serwer HTTP. Jeśli chcemy, aby serwer zasugerował nazwę pliku do pobrania, musimy poinformować przeglądarkę, że jest „OK”, aby JavaScript uzyskał dostęp do innych nagłówków, do których byłaby przesyłana sugerowana nazwa pliku.
Załóżmy - ze względu na dyskusję - że chcemy, aby serwer przesyłał sugerowaną nazwę pliku w nagłówku HTTP o nazwie X-Suggested-Filename . Serwer HTTP informuje przeglądarkę, że jest OK , aby wystawiać odebrany niestandardowy nagłówek z JavaScript / Axios z następującym nagłówkiem:
Access-Control-Expose-Headers: X-Suggested-Filename
Dokładny sposób konfiguracji serwera HTTP w celu ustawienia tego nagłówka różni się w zależności od produktu.
Zobacz https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Headers, aby uzyskać pełne wyjaśnienie i szczegółowy opis tych standardowych nagłówków.
2. Zaimplementuj usługę po stronie serwera
Twoja implementacja usługi po stronie serwera musi teraz wykonywać 2 rzeczy:
1. Create the (binary) document and assign correct ContentType to the response
2. Assign the custom header (X-Suggested-Filename) containing the suggested file name for the client
Odbywa się to na różne sposoby, w zależności od wybranego stosu technologii. Naszkicuję przykład wykorzystując standard JavaEE 7, który powinien emitować raport w Excelu:
@GET
@Path("/report/excel")
@Produces("application/vnd.ms-excel")
public Response getAllergyAndPreferencesReport() {
// Create the document which should be downloaded
final byte[] theDocumentData = ....
// Define a suggested filename
final String filename = ...
// Create the JAXRS response
// Don't forget to include the filename in 2 HTTP headers:
//
// a) The standard 'Content-Disposition' one, and
// b) The custom 'X-Suggested-Filename'
//
final Response.ResponseBuilder builder = Response.ok(
theDocumentData, "application/vnd.ms-excel")
.header("X-Suggested-Filename", fileName);
builder.header("Content-Disposition", "attachment; filename=" + fileName);
// All Done.
return builder.build();
}
Usługa emituje teraz dokument binarny (w tym przypadku raport programu Excel), ustawia prawidłowy typ zawartości - a także wysyła niestandardowy nagłówek HTTP zawierający sugerowaną nazwę pliku do użycia podczas zapisywania dokumentu.
3. Zaimplementuj procedurę obsługi Axios dla otrzymanego dokumentu
Jest tu kilka pułapek, więc upewnijmy się, że wszystkie szczegóły są poprawnie skonfigurowane:
- Usługa odpowiada na @GET (tj. HTTP GET), więc wywołanie axios musi mieć postać „axios.get (...)”.
- Dokument jest przesyłany jako strumień bajtów, więc musisz powiedzieć Axios, aby traktował odpowiedź jako obiekt BLOB HTML5. (Tj. Typ odpowiedzi: „blob” ).
- W tym przypadku do otwierania okna przeglądarki używana jest biblioteka JavaScript do zapisywania plików. Możesz jednak wybrać inny.
Szkieletowa implementacja Axios wyglądałaby wtedy następująco:
// Fetch the dynamically generated excel document from the server.
axios.get(resource, {responseType: 'blob'}).then((response) => {
// Log somewhat to show that the browser actually exposes the custom HTTP header
const fileNameHeader = "x-suggested-filename";
const suggestedFileName = response.headers[fileNameHeader];'
const effectiveFileName = (suggestedFileName === undefined
? "allergierOchPreferenser.xls"
: suggestedFileName);
console.log("Received header [" + fileNameHeader + "]: " + suggestedFileName
+ ", effective fileName: " + effectiveFileName);
// Let the user save the file.
FileSaver.saveAs(response.data, effectiveFileName);
}).catch((response) => {
console.error("Could not Download the Excel report from the backend.", response);
});