You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Express后端用sendFile返回文件,React前端如何处理该响应?

Handling Express File Responses in React

Got it, let's break down how to handle that file response from your Express backend in React. That locked: true ReadableStream you're seeing is totally expected—here's what's happening and how to properly process the file:

Why You're Seeing a Locked ReadableStream

When your Express server sends a file via sendFile, the browser returns the content as a readable stream. If you try to log the raw response body directly, or if you've already attempted to read the stream (even implicitly), it gets "locked" and can't be read again. Instead, we need to convert that stream into a Blob (binary large object) which we can work with for downloads or previews.

Solution 1: Using the Fetch API

Here's how to fetch the file and trigger a download in React:

const downloadFile = async (productFileName) => {
  try {
    const response = await fetch(`/your-express-route/${productFileName}`);
    // Convert the stream to a Blob
    const blob = await response.blob();
    // Create a temporary URL for the Blob
    const url = window.URL.createObjectURL(blob);
    // Create an invisible <a> tag to trigger download
    const a = document.createElement('a');
    a.href = url;
    // Set the filename for the downloaded file
    a.download = productFileName;
    document.body.appendChild(a);
    a.click();
    // Clean up: revoke the URL and remove the <a> tag
    window.URL.revokeObjectURL(url);
    document.body.removeChild(a);
  } catch (error) {
    console.error('Error downloading file:', error);
  }
};

Solution 2: Using Axios

If you're using Axios instead of fetch, make sure to set responseType: 'blob' in your request config—this tells Axios to handle the response as binary data:

import axios from 'axios';

const downloadFile = async (productFileName) => {
  try {
    const response = await axios.get(`/your-express-route/${productFileName}`, {
      responseType: 'blob' // Critical for handling binary files
    });
    const url = window.URL.createObjectURL(new Blob([response.data]));
    const a = document.createElement('a');
    a.href = url;
    a.download = productFileName;
    document.body.appendChild(a);
    a.click();
    window.URL.revokeObjectURL(url);
    document.body.removeChild(a);
  } catch (error) {
    console.error('Error downloading file:', error);
  }
};

Bonus: Previewing the File (e.g., Images/PDFs)

If you want to preview the file instead of downloading it (like showing an image or PDF), you can use the Blob URL directly in an <img> or <iframe> tag:

import { useState, useEffect } from 'react';

const FilePreview = ({ productFileName }) => {
  const [fileUrl, setFileUrl] = useState(null);

  const loadFilePreview = async () => {
    try {
      const response = await fetch(`/your-express-route/${productFileName}`);
      const blob = await response.blob();
      const url = window.URL.createObjectURL(blob);
      setFileUrl(url);
    } catch (error) {
      console.error('Error loading file preview:', error);
    }
  };

  // Clean up the Blob URL when component unmounts
  useEffect(() => {
    return () => {
      if (fileUrl) {
        window.URL.revokeObjectURL(fileUrl);
      }
    };
  }, [fileUrl]);

  return (
    <div>
      <button onClick={loadFilePreview}>Load Preview</button>
      {fileUrl && <img src={fileUrl} alt="Product file preview" style={{ maxWidth: '100%' }} />}
      {/* For PDFs, use an iframe instead: */}
      {/* {fileUrl && <iframe src={fileUrl} title="PDF Preview" width="100%" height="500px" />} */}
    </div>
  );
};

内容的提问来源于stack exchange,提问作者Javad Sameri

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 10:15:11