我正在使用Jersey2.0在Java中创建Web服务。当我执行来自 POSTMAN 的请求时,一切正常,但是当我执行来自客户端应用程序的请求时,我无法接收标头参数。我的客户端应用程序基于JavaScript。另外,我在 ContainerResponseContext 中添加了CORS允许来源请求参数。
以下显示了我的 ContainerResponseFilter 类,在其中添加了CORS。
@Provider
class CORSFilter : ContainerResponseFilter {
override fun filter(requestContext: ContainerRequestContext?, responseContext: ContainerResponseContext?) {
responseContext?.apply {
headers.add("Access-Control-Allow-Origin", "*")
headers.add("Access-Control-Allow-Headers", "origin, content-type, authorization, accept, privatekey")
headers.add("Access-Control-Allow-Credentials", "true")
headers.add("Access-Control-Allow-Methods", "GET, POST, PUT, DELETE, OPTIONS, HEAD")
}
}
}
私有密钥是我的请求标头名称。现在,这是我的 ContainerRequestFilter 的代码。
@Priority(AUTHENTICATION)
@Provider
class JsTokenFilterNeeded : JsBaseFilter(this::class.java.simpleName) {
override fun filter(request: ContainerRequestContext?) {
val path = request?.uriInfo?.path
val privateKeyHeaderValue = request?.getHeaderString("privatekey")
println("private key -> $privateKeyHeaderValue")
}
}
我总是在 privateKeyHeaderValue 中得到空值。这两个容器都已在 ResourceConfig 类中成功注册。
到目前为止,我在请求的资源上没有“ Access-Control-Allow-Origin”标头,这是日志。
{host=[203.***.51.***:5555], connection=[keep-alive], access-control-request-method=[GET], origin=[http://localhost:38596], user-agent=[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.121 Safari/537.36], access-control-request-headers=[privatekey], accept=[*/*], alexatoolbar-alx_ns_ph=[AlexaToolbar/alx-4.0.3], referer=[http://localhost:38596/], accept-encoding=[gzip, deflate], accept-language=[en-US,en;q=0.9]}
编辑1 这是我的客户端应用程序的Js代码。
$.ajax(
{
type: "GET",
headers: {
'privatekey': privateKey
},
url: "http://***.124.**.76:5555/dcu/energy/"+active_import,
data: {
'dcu_id': '99220445',
'tariff': 0
},
error: function (result) {
console.log(result);
},
success: function (result) {
console.log(result);
}
});
Edit2 我正在使用ResourceConfig来注册我的提供程序。这是我的ResourceConfig类。
class MyResourceConfig : ResourceConfig() {
init {
register(CORSFilter())
register(JsTokenFilterNeeded())
}
}
答案 0 :(得分:2)
在实际请求之前发生了preflight request。预检请求不发送任何标头(包括键标头)。它仅发送标头,询问服务器是否允许该请求。因此,当预检请求到达过滤器时,令牌将不存在。
您应该做的是使CorsFilter同时实现ContainerRequestFilter
和 ContainerResponseFilter
。将其设置为@PreMatching
过滤器。这样,它将在令牌过滤器之前被调用。在请求过滤器中,检查它是否是预检请求。如果是,则中止请求。这将导致请求跳过其余的请求过滤器,而直接进入响应过滤器。在响应过滤器一侧,您可以添加CORS标头。
您应该阅读这篇文章中的the UPDATE,以更好地了解CORS协议的流程,并更好地实现可使用的CorsFilter实施方案。