Angular Cli中Http Get正常但Post请求因CORS问题失败求助
看起来你遇到的核心问题是POST请求触发的浏览器预检OPTIONS请求没有被Servlet正确处理,再加上代理配置和请求地址的小错误,导致跨域失败。咱们一步步来解决:
1. 修正Angular请求的两个关键问题
用相对路径替代绝对路径
你当前的http.post用了完整的绝对URL http://192.168.1.6:8080/Observer/GetJson,这会绕过Angular的代理配置,直接向目标服务器发请求,导致跨域。改成相对路径,并移除不必要的请求头:
public authentication(email, password) { console.log("POST REQUEST"); // 只保留发送JSON请求体必需的头,CORS相关头是服务器返回给浏览器的,客户端无需发送 let headers = new Headers({ 'Content-Type': 'application/json' }); let options = new RequestOptions({ headers: headers }); // 使用相对路径,让代理拦截并转发请求 return this.http.post('/Observer/GetJson', { email: email, password: password }, options) .map( (response) => response.json() ) .subscribe( (data) => console.log(data) ) }
修正代理配置的pathRewrite
你的proxy.conf.json里的pathRewrite配置错误,会导致转发后的路径出现重复URL,正确的配置应该是:
{ "/Observer/*": { "target": "http://192.168.1.6:8080", "secure": false, "changeOrigin": true, // 保留/Observer前缀,让请求正确匹配到Servlet路径 "pathRewrite": { "^/Observer": "/Observer" } } }
如果你的Servlet路径本身就是/Observer/GetJson,甚至可以直接去掉pathRewrite字段,代理会自动将相对路径拼接到target地址后。
2. 处理Servlet的OPTIONS预检请求
POST请求因为带了Content-Type: application/json,属于浏览器定义的非简单请求,会先发送一个OPTIONS预检请求,询问服务器是否允许跨域。你的Servlet目前只处理了GET和POST,没有处理OPTIONS,所以预检请求返回的响应没有CORS头,导致浏览器报错。
在你的GetJson Servlet中添加doOptions方法:
@Override protected void doOptions(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // 允许所有源跨域 response.addHeader("Access-Control-Allow-Origin", "*"); // 允许的请求方法 response.addHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE, HEAD"); // 允许的请求头(要包含Angular请求中发送的Content-Type) response.addHeader("Access-Control-Allow-Headers", "Content-Type, x-requested-with"); }
这样预检请求就能得到正确的CORS响应,后续的POST请求就能正常到达doPost方法。
3. 验证步骤
- 重启Angular服务(确保代理配置生效):
npm start - 重启你的Java Servlet容器(比如Tomcat)
- 发起POST请求,现在应该能正常获取响应了
为什么GET请求正常?因为GET属于简单请求,浏览器不会发送预检OPTIONS,直接发送请求,而你的doGet方法返回了CORS头,所以浏览器允许响应。而POST因为是非简单请求,必须通过预检,所以才会出现报错。
内容的提问来源于stack exchange,提问作者Feroz Siddiqui

