未配置服务端CORS却遭遇跨域拦截问题求助
解决CORS阻塞问题:Failed to connect blocked by cors
错误信息
Access to fetch at 'http://localhost:3000/newPereferences' from origin 'http://localhost:3001' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
前端请求代码
async function changePereferences(newPereferences) { const response = await fetch('http://localhost:3000/newPereferences', { method: 'POST', body: JSON.stringify(newPereferences), headers: { 'Content-Type':'application/json', 'Access-Control-Allow-Origin':'*', 'Access-Control-Allow-Methods':'POST,PATCH,OPTIONS' } }); const resData = await response.json(); if(!response.ok) { throw new Error('Failed to update perevrences') }; return resData.message; }
服务端依赖配置
{ "name": "backend", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1" }, "keywords": [], "author": "", "license": "ISC", "dependencies": { "express": "^4.18.2" } }
服务端代码
const express = require('express'); const port = 3000; const fs = require('fs'); const app = express(); app.use(express.json()); //paths app.put('/newPereferences', async (req, res) => { const newPerevrences = req.body.newPerevrences; await fs.writeFile('./perevrences.json', JSON.stringify(newPerevrences)); res.status(200).json({ message: 'Perevrences updated successfully!'}) }) app.listen(port, () => { })
已尝试操作
添加了请求头{'Content-Type':'application/json', 'Access-Control-Allow-Origin':'*', 'Access-Control-Allow-Methods':'POST,PATCH,OPTIONS'},但问题未解决。
问题根源
- 请求头配置错误:
Access-Control-Allow-Origin、Access-Control-Allow-Methods是服务端返回的响应头,不是前端请求头,前端添加这些完全无效。 - 请求方法不匹配:前端用
POST请求,但服务端接口定义的是put,跨域下非简单请求会触发OPTIONS预检请求,服务端未处理该请求导致失败。 - 异步API使用错误:
fs.writeFile是回调式API,直接用await不会等待操作完成,会导致响应提前发送或文件写入失败。
修复方案
方案1:使用CORS中间件(推荐)
- 安装CORS依赖:
npm install cors
- 修改服务端代码:
const express = require('express'); const port = 3000; const fs = require('fs').promises; // 使用Promise版本的fs API const cors = require('cors'); const app = express(); app.use(cors()); // 启用跨域支持,允许所有源的请求 app.use(express.json()); // 把接口方法改为POST,和前端请求匹配 app.post('/newPereferences', async (req, res) => { try { const newPereferences = req.body.newPereferences; await fs.writeFile('./pereferences.json', JSON.stringify(newPereferences)); res.status(200).json({ message: 'Pereferences updated successfully!'}) } catch (err) { res.status(500).json({ message: 'Failed to update preferences' }); } }) app.listen(port, () => { console.log(`Server running on port ${port}`); })
- 调整前端代码,移除无效的CORS请求头:
async function changePereferences(newPereferences) { const response = await fetch('http://localhost:3000/newPereferences', { method: 'POST', body: JSON.stringify(newPereferences), headers: { 'Content-Type':'application/json' // 仅保留必要的Content-Type头 } }); const resData = await response.json(); if(!response.ok) { throw new Error('Failed to update preferences') }; return resData.message; }
方案2:手动处理CORS(无需中间件)
如果不想安装额外依赖,可手动设置响应头并处理OPTIONS请求:
const express = require('express'); const port = 3000; const fs = require('fs').promises; const app = express(); // 手动配置CORS响应头 app.use((req, res, next) => { res.setHeader('Access-Control-Allow-Origin', '*'); res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS'); res.setHeader('Access-Control-Allow-Headers', 'Content-Type'); // 处理OPTIONS预检请求 if (req.method === 'OPTIONS') { return res.sendStatus(200); } next(); }); app.use(express.json()); app.post('/newPereferences', async (req, res) => { try { const newPereferences = req.body.newPereferences; await fs.writeFile('./pereferences.json', JSON.stringify(newPereferences)); res.status(200).json({ message: 'Pereferences updated successfully!'}) } catch (err) { res.status(500).json({ message: 'Failed to update preferences' }); } }) app.listen(port, () => { console.log(`Server running on port ${port}`); })
内容的提问来源于stack exchange,提问作者TheKidWhoReallyCantCode
相关产品推荐
相关产品推荐

