简体   繁体   中英

How to keep the original filename in React when fetched from Django?

I'm working with a Django-Graphene-React stack and in my frontend, the user must be able to download a file from the backend.

It works perfectly.

However, the filename is defined in the backend and sent through the Content-Disposition header in the HttpRequest sent from Django. But I cannot retrieve it when I fetch it in the frontend.

Here is my backend Django view that generates the file:

import io

from django.http import HttpResponse


def download_file_view(request):
    buffer = io.BytesIO()
    # Generate an Excel file and put it a buffer...
    ...
    buffer.seek(0)
 
    response = HttpResponse(
        buffer.read(),
        content_type="application/vnd.openxmlformats-officedocument"
                     ".spreadsheetml.sheet",
    )

    # The filename is generated in the backend (Django) and cannot be
    # generated from the frontend (React)
    response["Content-Disposition"] = "filename.xlsx"

    return response

If I download it directly by entering the url assign to this view in my browser, I get the filename correctly when my browser prompt me to save the file.

However, I want to fetch the file in the frontend in order to get a loading state during the time the file is being generated in the backend.

Here is my frontend component in React:

import {useState) from "react";


const DownloadButton = ({downloadUrl}) => {
  const [isLoading, setIsLoading] = useState(false);

  const fetchExport = async() => {
    try {
      setIsLoading(true);
      const response = await fetch(downloadUrl);

      const header = response.headers.get("Content-Disposition");  // Empty
      console.log(response);  // Headers are empty

      const blob = await response.blob();

      let objectUrl = window.URL.createObjectURL(blob);
      let link = document.createElement("a");
      link.href = objectUrl;

      // By the way, these two lines clears my console and sometimes my
      // development server stops, I don't know why yet.
      link.click(); 
      link.remove(); 

    } catch (error) {
      console.log(error);
    } finally {
      setIsLoading(false);
    }
  }

  if (isLoading){
    return <div>Loading...</div>
  } else {
    return <div onClick={fetchExport}>Download</div>
}

So I get the file. This works fine. But instead of the original filename, I get my frontend url and some random uuid as filename.

I needed to add this in the django settings (using corsheaders).

CORS_EXPOSE_HEADERS = ['Content-Disposition']

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM