Tải xuống tệp (sử dụng Axios và Security)
Điều này thực sự còn phức tạp hơn khi bạn muốn tải tệp xuống bằng Axios và một số phương tiện bảo mật. Để tránh cho bất kỳ ai khác mất quá nhiều thời gian để tìm ra điều này, hãy để tôi hướng dẫn bạn qua điều này.
Bạn cần làm 3 điều:
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
Các bước này hầu hết đều có thể làm được - nhưng phức tạp đáng kể bởi mối quan hệ của trình duyệt với CORS. Một bước tại một thời điểm:
1. Định cấu hình máy chủ (HTTP) của bạn
Khi sử dụng bảo mật truyền tải, JavaScript thực thi trong trình duyệt [theo thiết kế] chỉ có thể truy cập 6 trong số các tiêu đề HTTP thực sự được gửi bởi máy chủ HTTP. Nếu chúng tôi muốn máy chủ đề xuất tên tệp để tải xuống, chúng tôi phải thông báo cho trình duyệt rằng "OK" để JavaScript được cấp quyền truy cập vào các tiêu đề khác nơi tên tệp được đề xuất sẽ được chuyển.
Chúng ta hãy giả sử - để thảo luận - rằng chúng ta muốn máy chủ truyền tên tệp được đề xuất trong tiêu đề HTTP được gọi là X-Suggested-Filename . Các máy chủ HTTP cho trình duyệt đó là OK để lộ tiêu đề tùy chỉnh nhận này để JavaScript / Axios với tiêu đề sau đây:
Access-Control-Expose-Headers: X-Suggested-Filename
Cách chính xác để định cấu hình máy chủ HTTP của bạn để đặt tiêu đề này khác nhau giữa các sản phẩm.
Xem https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Headers để biết giải thích đầy đủ và mô tả chi tiết về các tiêu đề chuẩn này.
2. Triển khai dịch vụ phía máy chủ
Việc triển khai dịch vụ phía máy chủ của bạn bây giờ phải thực hiện 2 điều:
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
Điều này được thực hiện theo nhiều cách khác nhau tùy thuộc vào công nghệ bạn đã chọn. Tôi sẽ phác thảo một ví dụ bằng cách sử dụng tiêu chuẩn JavaEE 7 sẽ tạo ra một báo cáo 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();
}
Dịch vụ hiện phát tài liệu nhị phân (trong trường hợp này là báo cáo Excel), đặt loại nội dung chính xác - và cũng gửi một tiêu đề HTTP tùy chỉnh có chứa tên tệp được đề xuất để sử dụng khi lưu tài liệu.
3. Triển khai trình xử lý Axios cho tài liệu Đã nhận
Có một số cạm bẫy ở đây, vì vậy hãy đảm bảo tất cả các chi tiết đều được định cấu hình chính xác:
- Dịch vụ trả lời @GET (tức là HTTP GET), vì vậy lệnh gọi axios phải là 'axios.get (...)'.
- Tài liệu được truyền dưới dạng một luồng byte, vì vậy bạn phải yêu cầu axios coi phản hồi như một HTML5 Blob. (Tức là responseType: 'blob' ).
- Trong trường hợp này, thư viện JavaScript trình tiết kiệm tệp được sử dụng để mở hộp thoại trình duyệt. Tuy nhiên, bạn có thể chọn cái khác.
Việc triển khai Axios khung sau đó sẽ là một cái gì đó dọc theo các dòng:
// 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);
});