the reading time is about 7 minutes.
in Web development, we often need to let users download some files, such as PDF, pictures, audio, video, etc. The common way is to have the background server return the file data stream, and then we download it through the download
attribute of the a
tag. This approach requires background support, but also has some limitations, such as the inability to download cross-domain files.
is there a way to download files directly at the front end?
the answer is yes, and you can download files at the front end without background service support through the createObjectURL
method.
this article details how to use createObjectURL
to download front-end files in React.
according to convention, look at the effect first and then talk about the method ~
createObjectURL method
createObjectURL
is a method for URL
objects to convert binary data or Blob
objects into URL that can be used on a page, usually for previewing or downloading files, or to display real-time streaming data from a camera or microphone on a page. The generated URL
object can be directly used in the src
attribute of media elements such as pictures, audio, video, etc., as well as the link address of the download file.
the URL
object generated using the URL
method is unique and becomes invalid as soon as the page is closed or reloaded. To avoid memory leaks, it is recommended that the URL.revokeObjectURL
method be called after use to release it.
download text file example
Let's take downloading a text file as an example to show how to use the createObjectURL
method to download a file in React.
first, we convert the text content to binary data through the Blob
object. For example, we convert a string to a Blob
object:
const content = "this is the content of a text file.";
const blob = new Blob([content], { type: 'text/plain' });
After
, we download the content locally in a txt file:
import React, { useState } from 'react';
function DownloadButton() {
const [content, setContent] = useState("this is the content of a text file.");
const handleClick = () => {
const blob = new Blob([content], { type: 'text/plain' });
const url = URL.createObjectURL(blob);
const link = document.createElement('a');
link.href = url;
link.download = 'file.txt';
document.body.appendChild(link);
link.click();
URL.revokeObjectURL(url);
document.body.removeChild(link);
};
return (
<button onClick={handleClick}>Download a file</button>
);
}
export default DownloadButton;
in the code above, we use the useState
hook function to define a state
to save the contents of the text file. In the button's click event function, we first use the Blob object to convert the text content to binary data, and then use the createObjectURL
method to convert it to a URL
object.
next, create a download link, set the URL
object to its href
property, and then simulate the user to click the link to download the file. Finally, release the URL
object and remove the download link from the page.
Note that because the event handler in React
automatically binds this
, the document
object and other global variables cannot be used directly in the event handler.
to solve this problem, we can use the useRef
hook function to create a ref
and add the link element to ref.current
. When the component is destroyed, use the useEffect
hook function to remove the link element.
the following is a sample code that uses the ref
attribute:
import React, { useState, useRef, useEffect } from "react";
function DownloadButton() {
const [content, setContent] = useState("this is the content of a text file.");
const linkRef = useRef<HTMLAnchorElement | null>(null);
const handleClick = () => {
const blob = new Blob([content], { type: "text/plain" });
const url = URL.createObjectURL(blob);
const link = document.createElement("a");
link.href = url;
link.download = "file.txt";
linkRef.current = link;
document.body.appendChild(link);
link.click();
URL.revokeObjectURL(url);
};
// manually remove the download link from the page when the component is destroyed
useEffect(() => {
return () => {
if (linkRef.current) {
document.body.removeChild(linkRef.current);
}
};
}, []);
return <button onClick={handleClick}>Download a file</button>;
}
export default DownloadButton;
in the above code, we use the useRef
hook function to create a ref
and add the link element to the ref.current
. When the component is destroyed, use the useEffect
hook function to remove the link element.
Summary
this article describes how to use the createObjectURL
method to download files in React. Using the createObjectURL
method allows us to easily download, preview, or play files at the front end without the support of the background server. Of course, for large files or files that need to be protected, it is still recommended that you use a background server to download.
Comments