Java Spark API配置Basic Auth后Angular 4调用报401预请求错误
解决Spark API中OPTIONS预检请求401的问题
问题根源
浏览器发送的OPTIONS预检请求是不带Basic Auth凭证的,但你的SecurityFilter会拦截/api/*下的所有请求(包括OPTIONS),直接返回401,导致前端出现Response for preflight has invalid HTTP status code 401错误。而Postman不会触发浏览器的预检机制,所以能正常调用接口。
解决方案
核心思路是让OPTIONS请求跳过Basic Auth验证,同时完善CORS响应头确保预检请求得到正确响应,具体修改如下:
1. 调整SecurityFilter逻辑,跳过OPTIONS请求
修改/api路径下的before拦截器,先判断请求方法,对OPTIONS预检请求直接放行,不执行安全验证:
path("/api", () -> { before("/*", (request, response) -> { // 对OPTIONS预检请求直接放行,不做Basic Auth验证 if ("OPTIONS".equalsIgnoreCase(request.requestMethod())) { return; } // 其他业务请求正常执行SecurityFilter验证 new SecurityFilter(authConfig, "DirectBasicAuthClient").handle(request, response); }); });
2. 完善OPTIONS请求的CORS响应头
在你的OPTIONS路由处理中,添加上Access-Control-Allow-Origin头,确保预检请求能拿到合法的跨域许可:
Spark.options("/*", (request, response) -> { String accessControlRequestHeaders = request.headers("Access-Control-Request-Headers"); if (accessControlRequestHeaders != null) { response.header("Access-Control-Allow-Headers", accessControlRequestHeaders); } String accessControlRequestMethod = request.headers("Access-Control-Request-Method"); if (accessControlRequestMethod != null) { response.header("Access-Control-Allow-Methods", accessControlRequestMethod); } // 添加上允许跨域的源,和全局设置保持一致 response.header("Access-Control-Allow-Origin", "*"); // 如果你的前端需要携带凭证(比如Cookie),请取消下面注释,同时Allow-Origin不能设为*,要指定具体域名 // response.header("Access-Control-Allow-Credentials", "true"); return "OK"; });
3. 保留全局跨域头设置
你原来的全局before拦截器可以继续保留,确保所有非OPTIONS请求也能拿到Access-Control-Allow-Origin头:
Spark.before((request, response) -> { response.header("Access-Control-Allow-Origin", "*"); });
生效原理
- OPTIONS预检请求会先被
Spark.options("/*")处理,返回符合要求的CORS响应头,同时在/api的before拦截器中跳过了SecurityFilter的验证,不会返回401。 - 实际的GET/POST等业务请求依然会经过SecurityFilter的Basic Auth验证,完全不影响接口的安全性。
内容的提问来源于stack exchange,提问作者damatano
相关产品推荐
相关产品推荐

