Angular 14请求拦截器添加Access-Control-Allow-Origin Header无效
问题描述
- 环境:Win10 + Angular 14,浏览器应用仅局域网内使用,通过
ng serve以非SSL方式运行 - 场景:向同局域网内的西门子LOGO PLC服务器发送POST请求
- 问题:服务器CORS配置无法修改,触发跨域错误:
CORS policy: Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource - 尝试操作:通过Angular HttpRequest拦截器添加
Access-Control-Allow-Origin: *请求头,但调试发现该头未被添加,请求头映射为空 - 拦截器代码:
import { Injectable } from '@angular/core'; import { HttpInterceptor, HttpRequest, HttpHandler, HttpEvent } from '@angular/common/http'; import { Observable } from 'rxjs'; @Injectable() export class CORSInterceptor implements HttpInterceptor { intercept(req: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> { // Clone the request to add the new header. const corsReq = req.clone({ headers: req.headers.set('Access-Control-Allow-Origin', '*'), }); // Send the newly created request return next.handle(corsReq); } }
问题原因
Access-Control-Allow-Origin是响应头而非请求头:这个头是服务器返回给浏览器的,用来指定允许访问资源的源。浏览器会自动过滤前端代码添加的这类CORS响应头,不会发送给服务器,所以调试时看不到该头。- 预检请求未通过校验:你的POST请求触发了浏览器的OPTIONS预检请求,而西门子PLC服务器没有返回
Access-Control-Allow-Origin等必要的CORS响应头,导致浏览器判定请求非法并拦截。 - Angular拦截器无法突破浏览器CORS机制:浏览器的CORS校验是在请求发出前的预检阶段完成的,Angular拦截器属于前端代码层面的修改,绕不开浏览器的安全限制。
解决办法
1. Angular代理配置(推荐开发环境使用)
通过本地代理转发请求,绕过浏览器CORS校验:
- 在项目根目录新建
proxy.conf.json文件:
{ "/plc-proxy": { "target": "http://[PLC服务器IP地址]", "secure": false, "changeOrigin": true, "pathRewrite": { "^/plc-proxy": "" } } }
- 修改
angular.json中的serve配置,添加代理文件路径:
"serve": { "builder": "@angular-devkit/build-angular:dev-server", "options": { "browserTarget": "你的项目名称:build", "proxyConfig": "proxy.conf.json" } }
- 发送请求时使用代理路径替代直接请求PLC地址:
this.http.post('/plc-proxy/你的接口路径', 请求数据);
2. 本地反向代理工具
使用Nginx、CORS Anywhere等工具搭建本地代理,将前端请求转发到PLC服务器,原理与Angular代理一致。
3. 关闭浏览器CORS校验(仅调试用)
Chrome浏览器可通过添加启动参数关闭CORS:
右键Chrome快捷方式→属性→目标栏末尾添加: --disable-web-security --user-data-dir="C:\MyChromeDevUserData"
注意:此方法仅适合开发调试,严禁用于生产环境,会带来安全风险。
内容的提问来源于stack exchange,提问作者BobC
相关产品推荐
相关产品推荐

