Angular 5跨域请求报错:请求资源无Access-Control-Allow-Origin头
解决Angular跨域请求403(预检请求未通过)的问题
首先得戳破一个常见误区:你在Angular服务里配置的跨域请求头根本起不到作用——CORS(跨域资源共享)的核心规则是由目标Web服务的服务器端来定义的,浏览器只会认服务器返回的Access-Control-Allow-Origin这类响应头,你在Angular请求里加的任何头都不会影响同源策略检查。
至于为什么Chrome直接访问和Postman能正常请求?原因很直白:
- Chrome地址栏的访问是普通页面请求,不属于AJAX范畴,不会触发浏览器的同源策略校验;
- Postman是独立的HTTP客户端,完全不受浏览器同源策略的限制,所以不管服务器有没有CORS配置都能拿到响应。
而Angular用HttpClient发起的是AJAX请求,跨域时浏览器会先发送一个OPTIONS预检请求,确认服务器允许这个跨域请求后,才会发送真正的业务请求。如果服务器没正确处理这个OPTIONS请求,或者没返回必要的CORS响应头,就会出现你看到的403错误。
具体排查与解决步骤
1. 确认服务器端是否正确配置了CORS响应头
你需要在目标Web服务的服务器上配置以下关键响应头(以允许http://localhost:4200为例):
Access-Control-Allow-Origin: http://localhost:4200(生产环境别用*,尽量指定具体域名)Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS(必须包含OPTIONS,因为预检请求用的就是这个方法)Access-Control-Allow-Headers: Content-Type, Authorization(如果你的请求带了自定义头或Content-Type: application/json,必须在这里明确列出)- 如果需要携带Cookie,还要加上
Access-Control-Allow-Credentials: true
2. 确保服务器正确处理OPTIONS预检请求
很多服务器默认会拦截OPTIONS请求,或者没有配置允许OPTIONS方法,这是导致403的高频原因。给你两个常见服务器的配置示例:
例子1:Node.js/Express 配置
用cors中间件并显式处理OPTIONS请求:
const express = require('express'); const cors = require('cors'); const app = express(); const corsOptions = { origin: 'http://localhost:4200', methods: ['GET', 'POST', 'PUT', 'DELETE', 'OPTIONS'], allowedHeaders: ['Content-Type', 'Authorization'], credentials: true }; // 全局应用CORS配置 app.use(cors(corsOptions)); // 显式处理所有OPTIONS请求 app.options('*', cors(corsOptions));
例子2:Spring Boot 配置
通过配置类开启全局CORS:
@Configuration public class CorsConfig implements WebMvcConfigurer { @Override public void addCorsMappings(CorsRegistry registry) { registry.addMapping("/**") // 对所有接口生效 .allowedOrigins("http://localhost:4200") .allowedMethods("GET", "POST", "PUT", "DELETE", "OPTIONS") .allowedHeaders("*") .allowCredentials(true) .maxAge(3600); // 预检请求的缓存时长,减少重复OPTIONS请求 } }
3. 用浏览器开发者工具排查预检请求细节
打开Chrome开发者工具(F12),切换到Network标签:
- 触发Angular的请求,找到类型为
OPTIONS的预检请求 - 查看它的响应头:如果没有
Access-Control-Allow-Origin,说明服务器完全没配置CORS;如果有但值不包含http://localhost:4200,同样会报错 - 查看响应状态码:403说明服务器拒绝了OPTIONS请求,得去服务器端排查是否有防火墙、WAF或者安全规则拦截了OPTIONS方法
4. 检查你的Angular请求是否属于非简单请求
如果你的请求满足以下任一条件,就会触发预检请求:
- 使用了PUT、DELETE、PATCH等非GET/POST方法
- 设置了
Content-Type: application/json(默认的application/x-www-form-urlencoded属于简单请求) - 自定义了请求头(比如
Authorization)
这种情况下,服务器必须在OPTIONS响应中明确允许对应的方法和头,否则浏览器会直接拒绝后续的真实请求。
内容的提问来源于stack exchange,提问作者Rajashree Gr
相关产品推荐
相关产品推荐

