Zero background implementation File download: practical experience of using createObjectURL in React

May 15, 2023 1322hotness 0likes 0comments

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.


InterServer Web Hosting and VPS

Aaron

Hello, my name is Aaron and I am a freelance front-end developer

Comments