You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Angular-Ionic调用Java服务端DELETE接口被CORS拦截问题求助

DELETE请求跨域(CORS)报错排查

问题背景

  • 前端基于Angular-Ionic开发,运行地址为http://localhost:8100
  • 后端为自研Java HTTP服务,运行地址为http://localhost:8080
  • 故障现象:调用DELETE类型接口删除用户时触发CORS拦截,禁用浏览器CORS校验后接口可正常执行,确认业务逻辑本身无异常,需要实现普通用户无需修改浏览器配置即可正常访问的效果。

现有实现代码

前端请求逻辑

console.log('User Management Service Delete User()');
const myParams = new HttpParams().set('id', this.cookieService.get('AccessToken'));
console.log(myParams);
return this.http.delete(this.endpoint + 'users/delete', { params: myParams});

逻辑说明:从cookie中读取访问令牌作为id参数,发起DELETE请求到后端删除接口。

后端接口逻辑

public int serveUserDelete(HTTPServer.Request req, HTTPServer.Response resp) throws IOException {
    Map<String, String> params = req.getParams();
    String response;
    String paramvalue;
    String  accessToken;    
    
    resp.getHeaders().add("Content-Type", "application/json");
    resp.getHeaders().add("Access-Control-Allow-Origin", "*");
    resp.getHeaders().add("Access-Control-Allow-Headers", "*");
    resp.getHeaders().add("Access-Control-Allow-Credentials", "true");
    resp.getHeaders().add("id", "*");
    resp.getHeaders().add("Access-Control-Allow-Methods", "OPTIONS, DELETE, POST, GET, PATCH, PUT");
    
    response = "";
    // 从参数中读取id值
    if (params.containsKey("id")) {
        accessToken = params.get("id");
        System.out.println(accessToken);
        
    } else {
        accessToken = null;
    }
    response = um.userDelete(accessToken);
    resp.send(200, response);
    return 0;
}

代码中所有CORS相关响应头为排查故障过程中陆续添加的配置。

报错信息

Access to XMLHttpRequest at 'http://localhost:8080/umyServerUrl/users/delete?id=u@Yy0NZPLx%266HxYNF%23tv' 
from origin 'http://localhost:8100' 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.

报错核心:浏览器发送的预检(OPTIONS)请求响应未通过CORS校验,响应中不存在Access-Control-Allow-Origin头。

控制台调试输出

请求参数打印

HttpParams 
{updates: Array(1), 
cloneFrom: HttpParams, 
encoder: HttpUrlEncodingCodec, 
map: null}
cloneFrom: 
nullencoder: 
HttpUrlEncodingCodec {}[[Prototype]]:
Objectconstructor: class
HttpUrlEncodingCodecdecodeKey: ƒ 
decodeKey(key)decodeValue: ƒ 
decodeValue(value)encodeKey: ƒ 
encodeKey(key)encodeValue: ƒ 
encodeValue(value)[[Prototype]]: 
Objectmap: 
Map(1)[[Entries]]0: {"id" => Array(1)}
key: "id" value: ['hTxYusBwuB7pbUUCkW9E']size: 1[[Prototype]]:
Mapupdates: null[[Prototype]]: 
Object
user-management.service.ts:35 

返回对象打印

Observable {_isScalar: false, source: Observable, 
operator: MapOperator}
operator: MapOperator
project: res => res.body
length: 1
name: ""
arguments: (...)
caller: (...)
[[FunctionLocation]]: http.mjs:1300
[[Prototype]]: ƒ ()
[[Scopes]]: Scopes[2]
thisArg: undefined
[[Prototype]]: Object
call: ƒ call(subscriber, source)
constructor: class MapOperator
[[Prototype]]: Object
source: Observable
operator: FilterOperator {thisArg: undefined, predicate: ƒ}
source: Observable {_isScalar: false, source: Observable, operator: MergeMapOperator}
_isScalar: false
[[Prototype]]: Object
_isScalar: false
[[Prototype]]: Object

故障原因与修复方法

核心原因

DELETE属于非简单请求,浏览器会在实际发送DELETE请求前,先发送一个OPTIONS方法的预检请求,校验服务端是否允许跨域访问。当前后端仅在处理DELETE请求的serveUserDelete方法中添加了CORS响应头,没有针对OPTIONS请求做单独处理,预检请求到达服务端后拿不到合法的CORS响应头,直接被浏览器拦截。
另外现有CORS配置存在规则冲突:Access-Control-Allow-Credentials设为true时,Access-Control-Allow-Origin不允许使用通配符*,就算处理了OPTIONS请求,后续实际请求也会因为这个规则冲突被拦截。

修复步骤

  1. 给服务端新增OPTIONS方法的路由处理:针对/users/delete路径的OPTIONS请求,单独返回200状态码,同时携带全套CORS响应头,不需要执行删除用户的业务逻辑。如果服务端接口较多,可以写一个全局的CORS过滤器,所有请求进入业务逻辑前先判断是否是OPTIONS请求,是则直接返回CORS头和200状态码。
  2. 修正CORS配置冲突:将Access-Control-Allow-Origin的值从*改为动态读取请求头中的Origin字段值直接返回;Access-Control-Allow-Headers不要用*,明确配置允许的请求头,比如Content-Type, Authorization, id即可。
  3. 删除无效配置:resp.getHeaders().add("id", "*")不属于标准CORS响应头,没有实际作用,可以直接移除。

内容的提问来源于stack exchange,提问作者Lytrix

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 20:12:15