React+Axios向Heroku Rails后端发送POST/DELETE请求遇CORS问题
Rails后端CORS问题排查(POST/DELETE请求失败,GET正常)
问题详情
使用Axios从Netlify部署的React前端,向Heroku上的Rails后端发送请求时,GET请求正常,但POST和DELETE请求触发CORS错误。通过Postman测试POST/DELETE请求完全正常,已配置cors.rb但问题仍未解决。
当前cors.rb配置
Rails.application.config.middleware.insert_before 0, Rack::Cors do allow do origins 'https://wondrous-speculoos-749189.netlify.app' # Specify the domain that is allowed to access your API resource '/api/*', headers: :any, methods: [:get, :post, :put, :patch, :delete, :options, :head], credentials: true end end
React Vite前端代码
const [firstName, setFirstName] = useState(''); const [lastName, setLastName] = useState(''); const [deletePlayerId, setDeletePlayerId] = useState(''); const handlePlayerSubmit = async (e) => { e.preventDefault(); try { console.log(firstName, lastName) const response = await axios.post('https://agile-reef-32463-2ad3559c3e00.herokuapp.com/players', { player: { first_name: firstName, last_name: lastName, }, }); // Reset form values setFirstName(''); setLastName(''); console.log(response.data) } catch (error) { console.error(error); } }; const handleDeletePlayer = async (e) => { e.preventDefault(); try { console.log(player.first_name); await axios.delete(`https://agile-reef-32463-2ad3559c3e00.herokuapp.com/players/${deletePlayerId}`); // Reset form values setDeletePlayerId(''); } catch (error) { console.error(error); } };
解决方案
1. 修正CORS资源路径匹配
你的cors.rb配置的资源路径是/api/*,但前端请求的是/players(无/api前缀),导致CORS规则未匹配。两种修复方式:
- 后端路由统一添加
/api命名空间,前端请求改为/api/players; - 修改
cors.rb的resource规则,覆盖实际请求路径,例如:
Rails.application.config.middleware.insert_before 0, Rack::Cors do allow do origins 'https://wondrous-speculoos-749189.netlify.app' resource '/players', headers: :any, methods: [:get, :post, :put, :patch, :delete, :options, :head], credentials: true end end
如果需要匹配所有路径,可将resource设为'*'(注意全局匹配需谨慎)。
2. 确保Heroku部署生效
修改cors.rb后,必须重新部署到Heroku:
git add config/initializers/cors.rb git commit -m "fix: update CORS resource path to match players endpoint" git push heroku main
3. 处理OPTIONS预检请求
复杂请求会先发OPTIONS预检,确认Rails后端的Rack::Cors中间件未被自定义中间件拦截。若存在自定义中间件,需确保它允许OPTIONS请求通过。
4. 配置Axios凭证传递
如果请求需要携带Cookie等凭证,需给Axios添加withCredentials配置:
// 全局配置 axios.defaults.withCredentials = true; // 单个请求配置 await axios.post('https://agile-reef-32463-2ad3559c3e00.herokuapp.com/players', { player: { first_name: firstName, last_name: lastName } }, { withCredentials: true });
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

