Завантаження файлів (за допомогою Axios та Security)
Це насправді ще складніше, коли ви хочете завантажити файли за допомогою Axios та деяких засобів безпеки. Щоб хтось інший не витрачав занадто багато часу на це, дозвольте провести вас через це.
Вам потрібно зробити 3 речі:
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
Ці кроки здебільшого здійсненні, але вони значно ускладнюються відношенням браузера до CORS. Один крок за один раз:
1. Налаштуйте свій (HTTP) сервер
Застосовуючи транспортну безпеку, JavaScript, що виконується в браузері, може [за задумом] отримати доступ лише до 6 заголовків HTTP, які фактично надіслані сервером HTTP. Якщо ми хотіли б, щоб сервер запропонував ім'я файлу для завантаження, ми повинні повідомити браузер, що для «JavaScript» буде дозволено отримати доступ до інших заголовків, куди буде перенесено запропоноване ім’я файлу.
Припустимо - для обговорення - що ми хочемо, щоб сервер передавав запропоноване ім’я файлу в заголовку HTTP під назвою X-Suggested-Filename . Сервер HTTP повідомляє браузеру, що нормально виставляти цей отриманий користувацький заголовок JavaScript / Axios із таким заголовком:
Access-Control-Expose-Headers: X-Suggested-Filename
Точний спосіб налаштування сервера HTTP для встановлення цього заголовка залежить від продукту.
Подивитися Повне пояснення та детальний опис цих стандартних заголовків https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Headers .
2. Впровадити серверну службу
Тепер ваша реалізація серверної служби повинна виконувати 2 речі:
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
Це робиться різними способами залежно від обраного вами стеку технологій. Я накину приклад із використанням стандарту JavaEE 7, який повинен видавати звіт Excel:
@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();
}
Тепер служба випускає двійковий документ (у цьому випадку звіт Excel), встановлює правильний тип вмісту, а також надсилає власний заголовок HTTP, що містить запропоновану назву файлу, щоб використовувати під час збереження документа.
3. Впровадити обробник Axios для отриманого документа
Тут є кілька підводних каменів, тому давайте переконаємось, що всі деталі правильно налаштовані:
- Послуга реагує на @GET (тобто HTTP GET), тому виклик axios повинен бути 'axios.get (...)'.
- Документ передається як потік байтів, тому ви повинні сказати axios, щоб ставився до відповіді як до BLOB-масиву HTML5. (Тобто тип відповіді: "краплина" ).
- У цьому випадку для відкриття діалогового вікна браузера використовується бібліотека JavaScript для збереження файлів. Однак ви могли б вибрати інший.
Тоді скелет реалізації Axios мав би щось на зразок:
// 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);
});