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

React+FastAPI图片上传遇404错误,请求地址异常求助

React + FastAPI 文件上传404及语法错误解决方案

一、React代码问题及修复

  • 请求URL错误:原代码中fetch("http:/127.0.0.1:8000/files")少了一个斜杠,浏览器将其识别为相对路径,拼接前端域名后导致错误地址http://localhost:3000/127.0.0.1:8000/files。修复为完整绝对路径http://127.0.0.1:8000/files/(与FastAPI路由保持一致)。
  • 手动设置Content-Type错误:使用FormData上传文件时,无需手动指定image/jpeg,浏览器会自动生成带正确边界的multipart/form-data请求头,手动设置会导致服务器解析失败。直接删除该headers配置。
  • 响应处理重复调用json():response.json()已解析完响应流,再次调用会报错,直接打印解析后的结果即可。
  • 未阻止表单默认行为:点击按钮时表单会默认提交刷新页面,中断请求,在handleSubmit开头添加event.preventDefault()。
  • 冗余代码:const formDataJSON = JSON.stringify(formData);无实际作用,直接删除。

修正后的React代码:

import { useState, SyntheticEvent } from 'react';
import { Stack, Button } from '@mui/material';

const FileUpload = () => {
  const [selectedFiles, setSelectedFiles] = useState<File | null>(null);

  const fileChangeHandler = (e: React.ChangeEvent<HTMLInputElement>) => {
    if (e.target.files?.[0]) {
      setSelectedFiles(e.target.files[0]);
    }
  };

  const toggleDir2 = () => {
    // 补全你的toggleDir2逻辑
  };

  const handleSubmit = (event: SyntheticEvent) => {
    event.preventDefault();
    const formData = new FormData();
    if (selectedFiles) {
      formData.append("file", selectedFiles, selectedFiles.name);
    }
    const requestOptions = {
      method: "POST",
      body: formData,
    };

    fetch("http://127.0.0.1:8000/files/", requestOptions)
      .then((response) => {
        if (!response.ok) throw new Error("请求失败");
        return response.json();
      })
      .then((data) => {
        console.log(data);
      })
      .catch((err) => console.error(err));
  };

  return (
    <div>
      <Stack
        direction="row"
        spacing={10}
        justifyContent="center"
        alignItems="center"
      >
        <form>
          <fieldset>
            <input
              onChange={fileChangeHandler}
              name="image"
              type="file"
              accept=".jpeg, .png, .jpg"
            />
          </fieldset>
          <Button variant="contained" component="label" onClick={handleSubmit}>
            Upload Dir 1
          </Button>
        </form>
        <Button variant="contained" component="label" onClick={toggleDir2}>
          Upload Dir 2
        </Button>
      </Stack>
    </div>
  );
};

export default FileUpload;

二、FastAPI代码问题及修复

  • CORS配置错误:allow_origins=[origins]将数组嵌套为二维数组,导致CORS规则失效,改为直接传入origins数组。
  • File参数default设置错误:File(default='image/jpeg')用法错误,default应设为None表示可选,若必填则无需设置。推荐使用UploadFile替代bytes,更适合处理文件上传场景,支持获取文件名、流式读取等。
  • 拼写错误修正:原origins中的"http://localhos"修正为"http://localhost"。

修正后的FastAPI代码:

from fastapi import FastAPI, File, UploadFile
from fastapi.middleware.cors import CORSMiddleware

app = FastAPI()

origins = [
    "http://localhost.tiangolo.com",
    "https://localhost.tiangolo.com",
    "http://localhost",
    "http://localhost:3000"
]

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)


@app.get("/")
def read_root():
    return {"ping": "pong"}


@app.post("/files/")
async def create_file(file: UploadFile = File(...)):
    content = await file.read()
    return {"file_name": file.filename, "file_size": len(content)}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 23:51:17