在 Tomcat 8.0 中启用 CORS 响应过滤器

Posted

技术标签:

【中文标题】在 Tomcat 8.0 中启用 CORS 响应过滤器【英文标题】:Enabling a CORS Response Filter in Tomcat 8.0 【发布时间】:2014-10-16 00:26:34 【问题描述】:

我正在尝试使用相当基本的 jQuery.ajax POST 请求从另一台服务器(跨源)调用 Web 服务。

        return $.ajax(
            type: "POST",
            url: "http://dev.hostname.com/ws/account/example1@example.com?property_id=1&custnum=123456",
            dataType:"json"
        );

我总是收到以下error 回复...

XMLHttpRequest 无法加载 http://dev.hostname.com/ws/account/example1@example.com?property_id=1&custnum=123456。 请求中不存在“Access-Control-Allow-Origin”标头 资源。因此不允许使用原点http://localhost:63342 访问。

Web 服务是基于 Java 构建的基于 Jersey 的 Web 服务,托管在 Apache Tomcat/8.0.8 上。我尝试将请求作为 JSONP 发送,但是在尝试处理来自 promise 对象的回调时遇到了问题。然而,那是另一篇文章......作为替代方案,我决定研究实施 CORS 响应解决方案。现在我对 Java 编程非常陌生,对它不太熟悉,所以请多多包涵。

我研究了两种实现 CORS 的主要解决方案。一种是构建自定义响应过滤器。我无法让它工作,但后来发现自 Tomcat 7.0 以来,据说已经提供了一个过滤器。我已经看过关于第二种解决方案的几篇文章,但绝对没有运气。使用Apache Tomcat Documentation 中提供的指南,我将以下 FILTER 信息添加到应用程序的 web.xml 文件中(我也尝试将其添加到根目录的 web.xml 中,但在那里也不起作用)。

<filter>
    <filter-name>CorsFilter</filter-name>
    <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
    <init-param>
        <param-name>cors.allowed.origins</param-name>
        <param-value>*</param-value>
    </init-param>
    <init-param>
        <param-name>cors.allowed.methods</param-name>
        <param-value>GET,POST,HEAD,OPTIONS,PUT</param-value>
    </init-param>
    <init-param>
        <param-name>cors.allowed.headers</param-name>
        <param-value>Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers, Last-Modified</param-value>
    </init-param>
    <init-param>
        <param-name>cors.exposed.headers</param-name>
        <param-value>Access-Control-Allow-Origin,Access-Control-Allow-Credentials</param-value>
    </init-param>
    <init-param>
        <param-name>cors.support.credentials</param-name>
        <param-value>true</param-value>
    </init-param>
</filter>

<filter-mapping>
    <filter-name>CorsFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

因为我使用的是Tomcat 8.0.8。我原以为这会起作用,但我继续遇到同样的错误。我错过了什么吗?

感谢您的帮助。

更新

在 Firefox 中调用服务时,我正在添加来自 Firebug 的标头。这是请求标头...

Accept  application/json, text/javascript, */*; q=0.01
Accept-Encoding gzip, deflate
Accept-Language en-US,en;q=0.5
Cache-Control   no-cache
Connection  keep-alive
Content-Length  0
Host    dev.hostname.com
Origin  http://localhost:63342
Pragma  no-cache
Referer http://localhost:63342/keurig/default.html
User-Agent  Mozilla/5.0 (Windows NT 6.1; WOW64; rv:30.0) Gecko/20100101 Firefox/30.0

这是响应标头

Content-Length  0
Content-Type    text/plain
Date    Thu, 21 Aug 2014 17:50:58 GMT
Server  Apache-Coyote/1.1

我绝对看不到任何期望在响应中看到的“Access-Control-*”标头。

【问题讨论】:

首先尝试最小的设置,不要添加任何初始化参数,所以一切都保持默认。看看这是否有效,然后从那里添加其他配置属性,直到它停止工作。我可以在 Tomcat 7 上使用最小设置。 感谢 Gimby 的回复……遗憾的是没有变化。还有什么我可以忽略的吗?我是否必须在其他地方配置或安装某些东西才能注意配置文件。我问的原因是因为我已经尝试了我能想到的每一种配置组合,并且总是得到完全相同的响应。我本来预计错误行为会发生某种变化;一个新的错误什么的。实际上,我曾仔细检查过一次,以确保我正在调整正确的服务器! 是时候停止猜测,是时候开始使用 HTTP 嗅探器查看实际来回发送的内容了。 在原帖中添加了来自 Chrome 的网络信息。 改为使用 Firebug 中报告的标题... 【参考方案1】:

此处提供的 CORS 配置对我有用,但直到我删除了“允许的标题”中最后一个标题中逗号后的空格。

&lt;param-value&gt;Content-Type,X-Requested-With,accept,Origin,Access-Control-Request-Method,Access-Control-Request-Headers, Last-Modified&lt;/param-value&gt;

一旦我在“最后修改”之前取出了那个空间,我就开始做生意了。

【讨论】:

【参考方案2】:

在运行 Apache Tomcat/8.0.43 的旧版 Struts 2 应用程序中解决此问题的解决方案是在 web.xml 配置文件中的 Struts 2 过滤器之前添加 CORS 过滤器。

【讨论】:

以上是关于在 Tomcat 8.0 中启用 CORS 响应过滤器的主要内容,如果未能解决你的问题,请参考以下文章

为啥我需要在 tomcat 应用程序上启用 CORS

在 Java Servlet 上启用了 CORS,但从前端接收到 CORS 错误

在 Tomcat 8.0.30 上启用 CORS

为具有凭据支持的 tomcat 应用程序启用 CORS

响应标头中的 Azure 无服务器功能启用 CORS

在 node/express 中启用了 CORS,但得到“对预检请求的响应未通过访问控制检查”