Firefox中Quarkus后端DELETE/PUT请求预检CORS失败问题
奇怪的跨域CORS问题(Firefox下仅DELETE/PUT请求出错)
环境配置
后端(Quarkus)
ManagerController接口代码:
@Path("/rest/manager") @ApplicationScoped public class ManagerController { ... @GET @Path("/") public Response getManagerList() { ... } @POST @Path("/") public Response createManager(@Valid ManagerView managerView) { ... } @GET @Path("/{userId}") public Response getManager(@Parameter(required = true) @PathParam("userId") String userId) { ... } @DELETE @Path("/{userId}") public Response deleteManager(@Parameter(required = true) @PathParam("userId") String userId) { ... } @PUT @Path("/{userId}") public Response updateManager(@PathParam("userId") String userId, @Valid ManagerView managerView) { ... } }
application.properties配置:
quarkus.http.cors=true quarkus.http.cors.origins=http://localhost:3000 quarkus.http.cors.methods=GET,POST,PUT,DELETE,OPTIONS
前端(React + Axios)
POST请求示例:
.post<ManagerView>(`/manager`, managerToManagerView(data.manager), { headers: { Authorization: `Bearer ${data.accessToken}`, 'Content-Type': 'application/json', }, })
DELETE请求示例:
.delete<boolean>(`/manager/${userId}`, { headers: { Authorization: `Bearer ${data.accessToken}`, }, })
- 前端运行地址:
localhost:3000 - 后端运行地址:
localhost:8080
错误现象
Firefox中发起DELETE请求时触发跨域错误:
XHR OPTIONS http://localhost:8080/rest/manager/auth0|63de17288141500bc6ac65e0 CORS Missing Allow Origin Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:8080/rest/manager/auth0|63de17288141500bc6ac65e0. (Reason: CORS header ‘Access-Control-Allow-Origin’ missing). Status code: 400. Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:8080/rest/manager/auth0|63de17288141500bc6ac65e0. (Reason: CORS request did not succeed). Status code: (null).
问题特征:
- 仅DELETE、PUT请求出错,POST、GET请求正常;
- 仅Firefox存在该问题,Chrome、Edge无异常;
- Chrome中不携带Authorization头时请求无法正常工作;
- 尝试过多种Quarkus CORS配置,均未解决。
排查与解决方案
1. 确保OPTIONS预检请求被正确处理
Firefox对预检请求的校验更严格,若后端拦截器(如JWT校验)提前拦截了OPTIONS请求,会导致CORS头未正确返回。可添加全局OPTIONS处理器:
@Path("/") public class CorsOptionsHandler { @OPTIONS @Path("{path:.*}") public Response handleOptions() { return Response.ok() .header("Access-Control-Allow-Origin", "http://localhost:3000") .header("Access-Control-Allow-Methods", "GET,POST,PUT,DELETE,OPTIONS") .header("Access-Control-Allow-Headers", "Authorization,Content-Type") .header("Access-Control-Max-Age", "86400") .build(); } }
2. 完善Quarkus CORS配置
明确允许Authorization等自定义请求头,更新application.properties:
quarkus.http.cors=true quarkus.http.cors.origins=http://localhost:3000 quarkus.http.cors.methods=GET,POST,PUT,DELETE,OPTIONS quarkus.http.cors.headers=Authorization,Content-Type quarkus.http.cors.exposed-headers=* quarkus.http.cors.max-age=86400
3. 对URL中的特殊字符编码
userId包含|特殊字符,Firefox解析预检请求URL时可能出现异常。前端对userId进行URL编码:
.delete<boolean>(`/manager/${encodeURIComponent(userId)}`, { headers: { Authorization: `Bearer ${data.accessToken}`, }, })
Quarkus会自动解码PathParam,后端无需额外修改。
4. 让拦截器跳过OPTIONS请求
若使用JWT或其他请求拦截器,需跳过OPTIONS请求(预检请求不携带有效Authorization头,会被拦截返回400/401):
@Provider public class JwtAuthFilter implements ContainerRequestFilter { @Override public void filter(ContainerRequestContext requestContext) throws IOException { if ("OPTIONS".equalsIgnoreCase(requestContext.getMethod())) { return; } // 其他校验逻辑 } }
内容的提问来源于stack exchange,提问作者kronaemmanuel
相关产品推荐
相关产品推荐

