Kubernetes环境下FastAPI+React应用文件上传遇CORS问题求助
问题:Kubernetes环境下React+FastAPI文件上传遭遇CORS跨域问题
尝试在Kubernetes环境中实现React前端与FastAPI后端配合完成文件上传至数据库,但反复遇到CORS跨域问题,查阅多篇资料后仍未解决。
相关代码与配置
FastAPI代码
from fastapi import ( APIRouter, Depends, HTTPException, UploadFile, File ) from fastapi import FastAPI, File, UploadFile from fastapi.responses import JSONResponse from fastapi.middleware.cors import CORSMiddleware import httpx app = FastAPI() # Add CORS middleware to the app (not to the router) app.add_middleware( CORSMiddleware, allow_origins=["*"], # Allows all origins allow_credentials=True, allow_methods=["*"], # Allows all methods allow_headers=["*"], # Allows all headers ) router = APIRouter( prefix="/api", tags=["api"], responses={404: {"description": "404 Page Not Found"}}, ) @router.get("/") async def read_items(): return "<h1>Page</h1>" @router.post("/upload") async def upload(file: UploadFile = File(...)): print("Upload") app.include_router(router) if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=20000)
FastAPI的Kubernetes Deployment配置
apiVersion: apps/v1 kind: Deployment metadata: name: api-deployment labels: app: api spec: replicas: 1 selector: matchLabels: app: api template: metadata: labels: app: api spec: containers: - name: api image: api:latest imagePullPolicy: Never ports: - containerPort: 12980 name: web
FastAPI的Kubernetes Service配置
apiVersion: v1 kind: Service metadata: name: api-service spec: selector: app: api ports: - name: http protocol: TCP port: 20000 targetPort: 20000
Nginx代理配置(尚未转发请求,先验证预检请求)
server { listen 80; server_name api.localhost; add_header 'Access-Control-Allow-Origin' $http_origin; add_header 'Access-Control-Allow-Credentials' 'true'; add_header 'Access-Control-Allow-Headers' 'Authorization,Accept,Origin,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range'; add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS,PUT,DELETE,PATCH'; location / { if ($request_method = 'OPTIONS') { add_header 'Access-Control-Max-Age' 1728000; add_header 'Content-Type' 'text/plain charset=UTF-8'; add_header 'Content-Length' 0; add_header 'Access-Control-Allow-Origin' $http_origin; add_header 'Access-Control-Allow-Credentials' 'true'; add_header 'Access-Control-Allow-Headers' 'Authorization,Accept,Origin,DNT,X-CustomHeader,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Content-Range,Range'; add_header 'Access-Control-Allow-Methods' 'GET,POST,OPTIONS,PUT,DELETE,PATCH'; } proxy_redirect off; proxy_set_header host $host; proxy_set_header X-real-ip $remote_addr; proxy_set_header X-forward-for $proxy_add_x_forwarded_for; # proxy_pass http://cos-service.default.svc.cluster.local:20000/; } }
Nginx的Kubernetes Deployment配置
apiVersion: apps/v1 kind: Deployment metadata: name: nginx-cors labels: app: nginx-cors spec: replicas: 1 selector: matchLabels: app: nginx-cors template: metadata: labels: app: nginx-cors spec: containers: - name: nginx-cors image: nginx-cors:latest imagePullPolicy: Never ports: - containerPort: 80 name: nginx
Nginx的Kubernetes Service配置
apiVersion: v1 kind: Service metadata: name: nginx-svc spec: selector: app: nginx-cors ports: - name: http protocol: TCP port: 11999 targetPort: 80
React前端代码
import React, { useState, ChangeEvent, FormEvent } from 'react'; import axios from 'axios'; const FileUpload: React.FC = () => { const [selectedFile, setSelectedFile] = useState<File | null>(null); const [uploadProgress, setUploadProgress] = useState<number>(0); const handleFileChange = (event: ChangeEvent<HTMLInputElement>) => { if (event.target.files && event.target.files.length > 0) { setSelectedFile(event.target.files[0]); } }; const handleUpload = async (event: FormEvent) => { event.preventDefault(); if (!selectedFile) { alert('Please select a file first'); return; } const formData = new FormData(); formData.append('file', selectedFile); console.log("formdata ", formData); try { const response = await axios.post('http://nginx-svc:11999/', formData, { headers: { 'Content-Type': 'multipart/form-data', }, onUploadProgress: (progressEvent) => { const percentCompleted = Math.round((progressEvent.loaded * 100) / progressEvent.total); setUploadProgress(percentCompleted); }, }); if (response.status === 201) { alert('File uploaded successfully'); } else { alert('File upload failed'); } } catch (error) { console.error('Error uploading file:', error); alert('Error uploading file'); } }; return ( <div> <form onSubmit={handleUpload}> <input type="file" onChange={handleFileChange} /> <button type="submit">Upload File</button> </form> {uploadProgress > 0 && <p>Upload Progress: {uploadProgress}%</p>} </div> ); }; export default FileUpload;
错误现象
点击上传按钮后,浏览器出现CORS错误,Firefox的网络调试信息如下:
恳请帮忙排查问题所在。
内容的提问来源于stack exchange,提问作者SSB
相关产品推荐
相关产品推荐




