React前端点击按钮调用API下载指定路径文件代码问题求助
React 文件下载功能修正方案
错误原因
- 事件绑定错误:
onClick属性直接传入了view(item.assignmentfilepath)的执行结果,组件渲染阶段就会自动调用该函数,点击按钮时没有绑定实际的处理函数,所以不会触发逻辑 view函数为空,没有实现文件请求、下载的相关逻辑- 表格结构不规范:
map循环时错误地为每条数据生成了单独的TableBody,正确结构应该是一个TableBody下循环生成TableRow - 路径适配问题:接口返回的文件路径使用Windows格式反斜杠,前端处理时容易出现转义异常
修正后的完整代码
import React, { useState, useEffect } from "react"; import axios from "axios"; import moment from "moment"; import { Grid, Paper, Typography, Table, TableCell, TableContainer, TableHead, TableRow, TableBody, } from "@mui/material"; import Download from './Download'; import FileDownload from "js-file-download"; export default function Classroomtest() { const uid = localStorage.getItem("uniqueid"); const [assignments, setassignments] = useState(""); useEffect(() => { axios .get(`http://localhost:5000/api/v1/app/get-my-assignments/${uid}`) .then((res) => { setassignments(res.data); }) .catch(err => console.log('获取作业列表失败', err)); }, []); const view = async (path) =>{ // 转换路径中的反斜杠为正斜杠避免转义问题 const formatPath = path.replace(/\\/g, '/') try { // 替换为你实际的文件下载接口地址 const res = await axios.get('http://localhost:5000/api/v1/app/download-file', { params: { filePath: formatPath }, responseType: 'blob' // 必须指定返回类型为blob,才能正确处理二进制文件 }) // 从路径中提取原始文件名 const fileName = formatPath.split('/').pop() // 触发浏览器下载 FileDownload(res.data, fileName) } catch (err) { console.error('下载失败', err) } } return ( <Grid> <Paper sx={{ padding: 3, margin: 1, }} > <TableContainer component={Paper} sx={{ margin: "10px", width: "97%", }} > <Table sx={{ minWidth: 100 }} aria-label="simple table"> <TableHead> <TableRow> <TableCell align="right">Topic</TableCell> <TableCell align="right">Due</TableCell> <TableCell align="right">Action</TableCell> <TableCell align="right">Delete</TableCell> </TableRow> </TableHead> {/* 修正TableBody位置 */} <TableBody> {assignments?.data?.myassignments.map((item) => ( <TableRow key={item._id}> <TableCell align="right">{item.assignmentname}</TableCell> <TableCell align="right">{moment.utc(item.duedate).format("MMMM,DD")}</TableCell> <TableCell align="right"> {/* 修正事件绑定,用箭头函数包裹,点击时才触发调用 */} <button type="button" onClick={() => view(item.assignmentfilepath)}>Download</button> </TableCell> <TableCell align="right">Java</TableCell> </TableRow> ))} </TableBody> </Table> </TableContainer> </Paper> </Grid> ); }
注意事项
- 请将代码中的下载接口地址
http://localhost:5000/api/v1/app/download-file替换为你后端实际提供的文件下载接口路由 - 后端接口需要支持接收
filePath参数,返回对应文件的二进制流即可
内容的提问来源于stack exchange,提问作者Subhodeep bhowmick
相关产品推荐
相关产品推荐

