React上传文件至AWS API Gateway遇CORS及TypeError问题求助
问题描述
在React中向AWS API Gateway发送PUT请求上传文件时,遇到两个问题:
- 跨域预检拦截错误:
access to fetch URL blocked by cors preflight,但该请求在Postman中可正常执行 - 同时触发TypeError:
error TypeError: Failed to fetch at Upload (Upload.js:28:1)
附上相关代码,期望实现与Postman一致的文件上传效果:
import axios from 'axios'; import React,{Component} from 'react'; import { useState } from 'react'; export default function Upload(){ const [data,setData] = useState() if (data) { const file = (data.target.files[0]) console.log(file) const myHeaders = new Headers(); myHeaders.append("Content-Type", "image/jpeg"); const formdata = new FormData(); formdata.append('File', file); const requestOptions = { method: 'PUT', headers: myHeaders, body: formdata, redirectXXX: 'manual' }; fetch("https://XXXX.execute-api.us-east-1.amazonaws.com/prod/XXXX/IMG_0733.jpg", requestOptions) .then(response => response.text()) .then(result => console.log(result)) .catch(error => console.log('error', error)); } return ( <div> <form> <input type="file" onChange={(e) => setData(e)}/> </form> </div> ) }
解决方案
1. 修复AWS API Gateway的CORS配置
Postman不会触发浏览器的CORS预检机制,而React运行在浏览器环境中,会自动发送OPTIONS预检请求,必须确保API Gateway的CORS配置完全适配:
- 进入AWS控制台的API Gateway,定位到目标API
- 开启CORS配置,确保允许的HTTP方法包含
PUT和OPTIONS - 设置允许的Origin为你的React应用域名(测试阶段可临时用
*,生产环境务必指定具体域名) - 确认响应头配置包含
Access-Control-Allow-Headers、Access-Control-Allow-Methods等必要字段
2. 修正请求代码中的错误
你的代码存在3个关键问题,直接导致请求失败:
- 无效参数:
redirectXXX是拼写错误,应改为标准字段redirect: 'manual' - 错误设置Content-Type:当请求体为
FormData时,浏览器会自动生成带boundary的正确Content-Type,手动设置image/jpeg会破坏表单数据格式,导致后端无法解析 - 渲染逻辑问题:
if(data)会在组件每次渲染时执行,容易重复触发请求,应将请求逻辑封装为独立处理函数
修正后的代码示例:
import React, { useState } from 'react'; export default function Upload(){ const [file, setFile] = useState(null); const handleUpload = () => { if (!file) return; const formData = new FormData(); formData.append('File', file); const requestOptions = { method: 'PUT', body: formData, redirect: 'manual' }; fetch("https://XXXX.execute-api.us-east-1.amazonaws.com/prod/XXXX/IMG_0733.jpg", requestOptions) .then(response => { if (!response.ok) throw new Error(`HTTP错误: ${response.status}`); return response.text(); }) .then(result => console.log('上传成功:', result)) .catch(error => console.log('上传失败:', error)); } return ( <div> <form> <input type="file" onChange={(e) => setFile(e.target.files[0])} /> <button type="button" onClick={handleUpload}>上传文件</button> </form> </div> ) }
3. 验证API Gateway集成配置
- 检查PUT方法的集成请求是否正确处理FormData格式的请求体
- 如果对接的是S3,确认S3桶的权限策略允许API Gateway写入文件
- 确保API Gateway的阶段部署已更新,所有配置修改都已生效
内容的提问来源于stack exchange,提问作者lb2020
相关产品推荐
相关产品推荐

