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.