cleaner way to download files, use modern fetch API

This commit is contained in:
Lendemor 2024-04-09 18:41:58 +02:00
parent c28830f9eb
commit 802ed6df71
2 changed files with 26 additions and 12 deletions
reflex
.templates/web/utils
staticfiles.py

View File

@ -159,19 +159,33 @@ export const applyEvent = async (event, socket) => {
} }
if (event.name == "_download") { if (event.name == "_download") {
const a = document.createElement("a"); const getFilenameFromUrl = (url) => url.split("/").pop().split("?")[0];
a.hidden = true;
// Special case when linking to uploaded files (when rx.download is returned from upload_files handler.) // if the URL come from an upload handler, replace the backend URL placeholder with the actual backend URL
a.href = event.payload.url.replace( const downloadUrl = event.payload.url.replace(
"${getBackendURL(env.UPLOAD)}", "${getBackendURL(env.UPLOAD)}",
getBackendURL(env.UPLOAD) getBackendURL(env.UPLOAD)
); );
if (event.payload.filename) { const filename = event.payload.filename || getFilenameFromUrl(downloadUrl);
a.href = a.href + "?filename=" + event.payload.filename; fetch(downloadUrl, {
} method: "GET",
a.download = event.payload.filename; headers: { "X-Filename": filename },
a.click(); })
a.remove(); .then((response) => {
if (!response.ok)
throw new Error(`Download of file at ${downloadUrl} failed`);
return response.blob();
})
.then((blob) => {
const blobURL = window.URL.createObjectURL(blob);
const a = document.createElement("a");
console.log("Downloading file from ", blobURL, " as ", filename);
a.href = blobURL;
a.download = filename;
a.click();
window.URL.revokeObjectURL(blobURL);
})
.catch((error) => console.log(error));
return false; return false;
} }

View File

@ -20,8 +20,8 @@ class UploadedFiles(StaticFiles):
The response for the static file with download headers. The response for the static file with download headers.
""" """
req = Request(scope) req = Request(scope)
if "filename" in req.query_params: if "x-filename" in req.headers:
filename = req.query_params["filename"] filename = req.headers["x-filename"]
content_disposition = f'attachment; filename="{filename}"' content_disposition = f'attachment; filename="{filename}"'
else: else:
content_disposition = "attachment" content_disposition = "attachment"