Hỏi cách code download file zip trong Flask và ReactJs

Chào cả nhà,
Mình đang làm một phần nhỏ cho ứng dụng của mình, hiện tại mình cần cho phép client download file từ server.
Trên server code bằng flask, mình có dùng

try:
  current_dir = os.path.dirname(os.path.realpath(__file__))
  file_path = os.path.join(current_dir, "backups.zip")
  return send_file(file_dir, as_attachment=True)
except Exception as e:
  return {"message": str(e)}, 500

Mình dùng trình duyệt hoặc swagger thì nó tải bình thường, giờ vấn đề mình gặp là chưa biết cách tải từ client mình code bằng reactJS có sử dụng thư viện axios. Mình tải về nó ra 1 file zip trống trơn không có nội dung. Sau khi research một hồi thì mình có thấy cách dùng như sau:

// Call API
export function exportDatabase(filename, password) {
  return axios({
    method: Methods.GET,
    url: `/exporter/database`,
    params: buildQuery({ filename, password }),
    responseType: 'arraybuffer',
  });
}

// Xử lý
 exportDatabase(fileNameToExport, password)
        .then((response) => {
          const url = window.URL.createObjectURL(new Blob([response.data]));
          const link = document.createElement('a');
          link.href = url;
          const filename = response.headers['content-disposition'].split(
            'filename=',
          )[1];
          link.setAttribute('download', filename); // or any other extension
          document.body.appendChild(link);
          link.click();

          setIsSubmitting(false);
          cleanState();
        })
        .catch((err) => {
          console.log('err.response :>> ', err.response);
          updateActionWithDatabase({
            errorMessage: err.response.data.toString(),
          });
          setIsSubmitting(false);
        });

Dùng cách này mình download được file ngon lành, nhưng lại gặp vấn đề khác là khi tải file bị gặp lỗi, server sẽ thảy ra một message lỗi. Lúc này ở client, mình không đọc được nội dung lỗi do là nó đang là dạng arraybuffer. Loay hoay cả ngày trời không được nên lên hỏi cả nhà tìm hướng xử lý.

Tiện mình cũng muốn hỏi làm sao để test download file như này bằng PostMan luôn, trước giờ mình chỉ làm với return text, json… đây là lần đầu mình làm việc với file và sẽ còn làm dài dài nên thiếu kiến thức ở đâu nhờ cả nhà chỉ luôn nhé.
Chân thành cảm ơn cả nhà nhiều

Minhf khi download trên client react thì hay dùng thư viện này


Bạn dùng thử xem

3 Likes

Postman hình như có cho save response như là 1 file

1 Like

Mình chưa hiểu cách để bắt exception từ server về, trong trường hợp của mình, nếu mình đổi responseType thành arraybuffer hoặc blob thì nếu request của mình trả về message báo lỗi thì mình chưa biết phải làm sao để đưa cái text đó ra để hiển thị cả.

bạn đã console được rồi thì việc hiển thị thông báo có gì khó đâu nhỉ, một dòng code đơn giản như alert cũng được mà

1 Like

Ý mình là mình k thể lấy text của cái thông báo ra được ấy, ở hình trên bạn có thể thấy cái err.response nó không có cái message từ server trả về, err.response.data lúc này là Blob, không phải message mình mong muốn. Mình chưa kiếm được cách để lấy message ra.

Mình clear 1 chút.

try:
  current_dir = os.path.dirname(os.path.realpath(__file__))
  file_path = os.path.join(current_dir, "backups.zip")
  return send_file(file_dir, as_attachment=True)
except Exception as e:
  return {"message": str(e)}, 500

Nếu lỗi, back-end sẽ trả về cái json như trên, nhưng ở client, lỗi nó nhảy vô catch, trong đó err.response.data lại là Blob chứ không phải json mình mong muốn ấy.

sao thấy nó có data.text() kìa gọi thử xem

2 Likes

Cảm ơn bác nhiều, mình làm được rồi, lần đầu làm cái này nên còn ngáo. Cảm ơn cả nhà đã chỉ giáo
Một lần nữa xin chân thành cảm ơn @banhmisg9509, @Le_Duy_Tung rất nhiều.

Mình gửi cái mình làm ở đây để người sau có thể coi nếu cần.

.catch((err) => {
          err.response.data.text().then((result) => {
            console.log('result :>> ', result);
          });
3 Likes

do bạn đang cast responseType là arraybuffer
bạn có thể chuyển blob thành string

tuy nhiên, bạn cần phải chụp tab network monitor trên trình duyệt để xem cụ thể response trả về cái gì
thường là response thành công mới chuyển thành blob

3 Likes

Đúng rồi, do lúc đầu nếu không cast response type thì file zip của mình bị hỏng k mở được, cast sang arraybuffer thì k đọc được text, google mãi mới ra cái blob á.

Cũng đúng, mình cần tìm hiểu kỹ hơn về cái này. Cảm ơn bạn rất nhiều.

2 Likes
83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?