在 Tomcat 8.0.30 上启用 CORS

Posted

技术标签:

【中文标题】在 Tomcat 8.0.30 上启用 CORS【英文标题】:Enable CORS on Tomcat 8.0.30 【发布时间】:2016-11-16 05:13:14 【问题描述】:

感谢任何帮助。

我在新部署的 Tomcat 8.0.30 上遇到了 CORS 问题。我不断收到以下错误。我使用 127.0.0.1 作为 API 服务器地址,而 192.168.1.100 是我的 HTTP 服务器的地址。

请求的资源上不存在“Access-Control-Allow-Origin”标头。因此,不允许访问 Origin '_http://192.168.1.100:8999'。响应的 HTTP 状态代码为 403。

通读整个 Tomcat 文档,在 tomcat web.xml 以及项目 web.xml 下添加了 cors 过滤器,但这里没有任何魔法发生,仍然出现相同的错误。使用 init-param 尝试了最小和高级,同样的错误。

我使用 Spring 4 作为我的 rest api 框架。项目编码部分还需要配置吗?

到目前为止,我已经完成了以下步骤:

在 web.xml 下添加 cors 过滤器,根据文档进行最小配置,不起作用 在 web.xml 下添加 cors 过滤器,完整配置,效果不佳。 尝试使用来自 http://software.dzhuvinov.com/cors-filter.html 的 cors 过滤器,但仍然无法正常工作

有什么建议吗?


添加 web.xml 配置 我尝试将 cors.allowed.origins 更改为 *,更改为 127.0.0.1,192.168.1.100,都不起作用, 删除凭据和 maxage

<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>http://192.168.1.100</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,Authorization</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>
</filter>
<filter-mapping>
  <filter-name>CorsFilter</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

由 Vishal 建议,将 tomcat 版本从 8.0 更改为 8.5,仍然是同样的问题

 XMLHttpRequest cannot load http://127.0.0.1:8080/leyutech-framework-gurunwanfeng/api/ad/getAdInfoByAdType.html?adType=0. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://192.168.1.100:8080' is therefore not allowed access. The response had HTTP status code 403.

【问题讨论】:

至少提供你添加到web.xml中的配置。我可以向您保证 Tomcat 文档是正确的,我自己使用过。但是很容易错过配置。 我不确定你是否在寻找这个:tomcat.apache.org/tomcat-8.0-doc/config/filter.html#CORS_Filter 嗨 Gimby 和 Azim,是的,我从文档中添加了最低配置和高级配置,它们都不起作用 @ShawnZhou:我想知道您使用的 tomcat 版本是否有问题。我相信我们过去也有类似的东西,但我不记得我们使用的是 Tomcat 还是 JBoss,并且那个特定版本有问题迫使我们升级 @Vishal Jumani,我也尝试了 8.5.3 版本,但仍然遇到同样的问题。 【参考方案1】:

我已经使用自定义过滤器来解决这个问题,我不知道为什么官方的 tomcat cors 过滤器在我的情况下不起作用,任何人都可以提出这背后的逻辑,我愿意尝试一下。

Original Post from Tobia

代码是从上面的链接修改的。

import java.io.IOException;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletResponse;

public class SimpleCORSFilter implements Filter 

    public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain) throws IOException, ServletException 
        HttpServletResponse response = (HttpServletResponse) res;
        response.setHeader("Access-Control-Allow-Origin", "*");
        response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");
        response.setHeader("Access-Control-Max-Age", "3600");
        response.setHeader("Access-Control-Allow-Headers", "x-requested-with");
        chain.doFilter(req, res);
    

    public void destroy() 
        // TODO Auto-generated method stub

    

    public void init(FilterConfig arg0) throws ServletException 
        // TODO Auto-generated method stub

    


当前项目下的web.xml配置

<filter>
    <filter-name>SimpleCORSFilter</filter-name>
    <filter-class>com.example.util.SimpleCORSFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>SimpleCORSFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

【讨论】:

这是一个让 CORS 正常工作的解决方案,【参考方案2】:

我曾经遇到过这个问题,我为 Jetty Web 应用程序开发了一个自定义处理程序。

也许它可以帮助你。

CORSHandler.hava

import java.io.IOException;

import org.eclipse.jetty.server.handler.HandlerWrapper;
import org.eclipse.jetty.server.Request;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.ServletException;

public class CORSHandler extends HandlerWrapper 

    public static final String ACCESS_CONTROL_ALLOW_ORIGIN = "Access-Control-Allow-Origin";
    public static final String ACCESS_CONTROL_ALLOW_HEADERS = "Access-Control-Allow-Headers";
    public static final String ACCESS_CONTROL_ALLOW_METHODS = "Access-Control-Allow-Methods";

    public CORSHandler() 
        super();
    

    public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
    
        // Allow Cross-site HTTP requests (CORS)
        response.addHeader(ACCESS_CONTROL_ALLOW_ORIGIN, "*");

        // Accept Content-Type in header
        response.addHeader(ACCESS_CONTROL_ALLOW_HEADERS, "content-type");

        // Accept GET, POST, PUT and DELETE methods
        response.addHeader(ACCESS_CONTROL_ALLOW_METHODS, "GET,POST,PUT,DELETE");

        if (_handler!=null && isStarted())
        
            _handler.handle(target,baseRequest, request, response);
        
    

Starter.java

import java.io.IOException;
import java.util.logging.Logger;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.SimpleFormatter;

import org.apache.cxf.transport.servlet.CXFServlet;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.eclipse.jetty.server.handler.HandlerWrapper;

import com.example.config.AppConfig;
import com.example.handlers.CORSHandler;

import com.example.properties.*;

public class Starter 

    public static void main( final String[] args ) throws Exception 

        Server server = new Server( 8080 );

        // Register and map the dispatcher servlet
        final ServletHolder servletHolder = new ServletHolder( new CXFServlet() );

        HandlerWrapper wrapper = new CORSHandler();
        final ServletContextHandler context = new ServletContextHandler();

        context.setContextPath( "/" );
        context.addServlet( servletHolder, "/rest/*" );     
        context.addEventListener( new ContextLoaderListener() );

        context.setInitParameter( "contextClass", AnnotationConfigWebApplicationContext.class.getName() );
        context.setInitParameter( "contextConfigLocation", AppConfig.class.getName() );

        wrapper.setHandler(context);
        server.setHandler(wrapper);

        server.start();
        server.join();  
    

【讨论】:

谢谢,我现在也在使用自定义过滤器,我不知道为什么原来的过滤器不起作用,我使用了***.com/questions/24386712/tomcat-cors-filter。你的帖子绝对是一个很棒的公会。

以上是关于在 Tomcat 8.0.30 上启用 CORS的主要内容,如果未能解决你的问题,请参考以下文章

Unable to load configuration. - bean - jar:file:/D:/apache-tomcat-8.0.30/web

Window下同一台服务器部署多个tomcat服务

linux 安装tomcat

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

CentOS7安装Tomcat8.X

Eclipse WTP:如何在 Tomcat 上启用 SSL?