Angular4与Node Server:预检请求未通过跨域访问控制校验
解决Angular4与Node服务器的跨域请求问题
这个问题是典型的跨域资源共享(CORS)问题,根源在于浏览器的同源策略:你的Angular应用跑在http://localhost:3000,Node服务器在http://localhost:3100,不同端口属于不同的源,浏览器会拦截跨域请求,除非服务器明确返回允许跨域的响应头。尤其是你的请求触发了预检OPTIONS请求,服务器没有正确处理这个请求,导致校验失败。
下面给你两种可行的解决方案:
方案一:手动添加CORS响应头并处理预检请求
直接在你的Node服务器代码中添加跨域相关的响应头,同时专门处理OPTIONS预检请求:
var http = require('http'); var formidable = require('formidable'); http.createServer(function(req, res) { // 设置允许跨域的响应头 res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000'); // 允许的请求方法 res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE'); // 允许的请求头(根据你的实际需求调整) res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type'); // 如果需要携带cookie,开启这个配置 res.setHeader('Access-Control-Allow-Credentials', true); // 专门处理预检OPTIONS请求:直接返回200状态码 if (req.method === 'OPTIONS') { res.writeHead(200); res.end(); return; } // 你的原有表单处理逻辑 if (req.method === 'POST' && req.url === '/postEmployee') { var form = new formidable.IncomingForm(); form.parse(req, function(err, fields, files) { // 这里写你的表单数据处理逻辑 res.writeHead(200, {'Content-Type': 'application/json'}); res.end(JSON.stringify({success: true, data: fields})); }); } else { res.writeHead(404); res.end(); } }).listen(3100);
方案二:使用cors npm包(更简洁可靠)
手动写CORS配置容易遗漏细节,推荐使用官方维护的cors包来处理:
- 先安装依赖:
npm install cors --save
- 修改服务器代码:
var http = require('http'); var formidable = require('formidable'); var cors = require('cors'); // 配置CORS规则,指定允许的源 const corsConfig = cors({ origin: 'http://localhost:3000', credentials: true // 允许携带cookie,不需要的话可以去掉 }); http.createServer(function(req, res) { // 先通过cors中间件处理跨域 corsConfig(req, res, function() { // 处理完跨域后,再执行你的业务逻辑 if (req.method === 'POST' && req.url === '/postEmployee') { var form = new formidable.IncomingForm(); form.parse(req, function(err, fields, files) { res.writeHead(200, {'Content-Type': 'application/json'}); res.end(JSON.stringify({success: true, data: fields})); }); } else { res.writeHead(404); res.end(); } }); }).listen(3100);
注意事项
- 如果后续部署到生产环境,记得把
origin的值改成你的前端应用实际域名,不要用*(如果需要携带cookie,*会导致credentials配置失效)。 - 预检请求是浏览器自动触发的,不需要你在Angular代码中额外发送,只要服务器正确处理就行。
内容的提问来源于stack exchange,提问作者user8079583
相关产品推荐
相关产品推荐

