1. 概述
本文将介绍如何在基于 JAX-RS 的系统中启用 CORS(跨域资源共享)机制。我们将通过一个 JAX-RS 应用示例,展示两种实现 CORS 的方法。
2. 启用 CORS 的两种方式
在 JAX-RS 中启用 CORS 主要有两种方案:
- 全局过滤器:通过过滤器自动为所有响应注入 CORS 头
- 手动注入:在每个接口单独添加 CORS 响应头
✅ 推荐使用过滤器方案,能统一管理且避免遗漏。
❌ 手动方案仅适用于少量接口的特殊场景,大型项目维护成本高。
2.1 使用过滤器方案
JAX-RS 提供了 ContainerResponseFilter
接口,用于全局处理 HTTP 响应。我们通过实现该接口创建自定义过滤器:
@Provider
public class CorsFilter implements ContainerResponseFilter {
@Override
public void filter(ContainerRequestContext requestContext,
ContainerResponseContext responseContext) throws IOException {
responseContext.getHeaders().add(
"Access-Control-Allow-Origin", "*");
responseContext.getHeaders().add(
"Access-Control-Allow-Credentials", "true");
responseContext.getHeaders().add(
"Access-Control-Allow-Headers",
"origin, content-type, accept, authorization");
responseContext.getHeaders().add(
"Access-Control-Allow-Methods",
"GET, POST, PUT, DELETE, OPTIONS, HEAD");
}
}
⚠️ 关键点说明:
- 必须使用
@Provider
注解,否则 JAX-RS 运行时无法发现该过滤器 Access-Control-Allow-Origin: *
表示允许所有域名访问,生产环境应替换为具体域名- 过滤器会自动处理所有接口的响应,无需重复配置
2.2 手动注入响应头方案
当无法使用全局过滤器时(比如遗留系统限制),可直接在接口方法中注入 CORS 头:
@GET
@Path("/")
@Produces({MediaType.TEXT_PLAIN})
public Response index() {
return Response
.status(200)
.header("Access-Control-Allow-Origin", "*")
.header("Access-Control-Allow-Credentials", "true")
.header("Access-Control-Allow-Headers",
"origin, content-type, accept, authorization")
.header("Access-Control-Allow-Methods",
"GET, POST, PUT, DELETE, OPTIONS, HEAD")
.entity("")
.build();
}
⚠️ 注意事项:
- 每个需要跨域的接口都要重复添加这些头,容易遗漏
- 修改 CORS 策略时需要更新所有相关接口
- 仅适用于接口数量极少的简单场景
3. 测试验证
启动应用后,可通过以下方式验证 CORS 配置:
3.1 使用 curl 检查响应头
HTTP/1.1 200 OK
Date : Tue, 13 May 2014 12:30:00 GMT
Connection : keep-alive
Access-Control-Allow-Origin : *
Access-Control-Allow-Credentials : true
Access-Control-Allow-Headers : origin, content-type, accept, authorization
Access-Control-Allow-Methods : GET, POST, PUT, DELETE, OPTIONS, HEAD
Transfer-Encoding : chunked
3.2 跨域 AJAX 测试
创建测试脚本(需运行在与 API 不同域的环境下):
function call(url, type, data) {
var request = $.ajax({
url: url,
method: "GET",
data: (data) ? JSON.stringify(data) : "",
dataType: type
});
request.done(function(resp) {
console.log(resp);
});
request.fail(function(jqXHR, textStatus) {
console.log("Request failed: " + textStatus);
});
};
💡 本地测试技巧:
将前端应用运行在不同端口(如 localhost:3000
),API 运行在 localhost:8080
,即可模拟跨域场景(端口不同即视为不同源)。
4. 总结
本文展示了在 JAX-RS 应用中实现 CORS 的两种方案:
- 过滤器方案:推荐用于生产环境,统一管理且维护成本低
- 手动注入方案:仅适用于特殊场景,需谨慎使用
完整示例代码可在 GitHub 获取。实际应用中,建议根据项目规模和安全需求选择合适方案。