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

如何不使用Axios实现React.js向Spring Boot REST API上传图片

React 使用 Fetch 上传文件到 Spring Boot API

首先修正你 React 代码里的关键问题,然后实现符合要求的文件上传逻辑:

1. 修正文件输入的状态保存

当前你的文件输入 onChange 事件保存的是文件路径字符串,我们需要获取实际的文件对象。修改为:

onChange={(e) => setImgOne(e.target.files[0])}

2. 实现上传函数

参照你之前的 fetch 调用写法,创建上传处理函数。注意文件上传必须使用 FormData 封装数据,且无需手动设置 Content-Type 头部(浏览器会自动添加正确的 multipart/form-data 及边界信息)。

修改后的完整 React 代码

import React, { useState } from 'react';
import Container from 'react-bootstrap/Container';
import Row from 'react-bootstrap/Row';
import Col from 'react-bootstrap/Col';
import Form from 'react-bootstrap/Form';
import Button from 'react-bootstrap/Button';
import Postview from '../componant/postview';
import Navigation from '../componant/navigation';
import Card from 'react-bootstrap/Card';
import '../pages/profile.css';

export default function Profile() {
    const userId = sessionStorage.getItem("userID");
    const [imgOne, setImgOne] = useState(null);
    const [postBody, setPostBody] = useState("");
    const [postTitle, setPostTitle] = useState("");

    const handlePostClick = async (e) => {
        e.preventDefault();
        
        if (!imgOne) {
            console.error("请选择要上传的图片");
            return;
        }

        try {
            const formData = new FormData();
            formData.append("File", imgOne); // 键名与 Spring Boot 接口的 @RequestParam 一致
            // 可选:同时上传标题和描述
            formData.append("title", postTitle);
            formData.append("body", postBody);

            const result = await fetch('http://localhost:8080/uploadFile', {
                method: 'POST',
                body: formData
            });

            if (result.ok) {
                const response = await result.text();
                console.log(response);
                // 上传成功后重置表单
                setImgOne(null);
                setPostTitle("");
                setPostBody("");
            } else {
                console.error("上传失败");
            }
        } catch (e) {
            console.error("请求出错:", e);
        }
    };

    return (
        <Container>
            <Navigation /><br />
            <Row>
                <Col md="9">
                    <Postview />
                </Col>
                <Col md="3">
                    <Card>
                        <Card.Body>
                            <Form>
                                <Form.Group className="mb-3" controlId="imageUpload">
                                    <Form.Label>Images</Form.Label>
                                    <Form.Control 
                                        type="file" 
                                        accept="image/*"
                                        onChange={(e) => setImgOne(e.target.files[0])} 
                                    />
                                </Form.Group>
                                <Form.Group className="mb-3" controlId="postTitle">
                                    <Form.Label>Title</Form.Label>
                                    <Form.Control 
                                        type="text"
                                        value={postTitle} 
                                        onChange={(e) => setPostTitle(e.target.value)} 
                                    />
                                </Form.Group>
                                <Form.Group className="mb-3" controlId="postBody">
                                    <Form.Label>Description</Form.Label>
                                    <Form.Control 
                                        as="textarea" 
                                        rows={3} 
                                        value={postBody} 
                                        onChange={(e) => setPostBody(e.target.value)} 
                                    />
                                </Form.Group>
                                <Button 
                                    id='postBtn' 
                                    variant="primary" 
                                    onClick={handlePostClick}
                                >
                                    Post
                                </Button>
                            </Form>
                        </Card.Body>
                    </Card>
                </Col>
            </Row>
        </Container>
    );
}

关键说明

  • FormData 封装: 文件上传必须通过 FormData 对象处理,这是浏览器支持 multipart/form-data 请求的标准方式。
  • 参数名一致性: formData.append("File", imgOne) 中的 "File" 必须与 Spring Boot 接口 @RequestParam("File") 的参数名完全匹配,否则后端无法接收文件。
  • Content-Type 自动处理: 不要手动设置 Content-Type,浏览器会自动添加包含边界标识的正确头部,手动设置会导致后端解析失败。
  • 异步逻辑: 使用 async/await 让请求逻辑更清晰,同时正确处理异步操作的结果与错误。

注:原代码中标题输入框使用 type="email" 疑似失误,已改为 type="text",若需邮箱类型可自行改回。

内容的提问来源于stack exchange,提问作者Dilan Tharaka

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.21 05:27:20