【问题标题】:CORS for localhost and domain本地主机和域的 CORS
【发布时间】:2021-01-28 23:43:01
【问题描述】:

我正在使用以下代码为基于 Java/Jersey 的 Web 应用程序设置 CORS。

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletResponse resp = (HttpServletResponse) response;
//      resp.addHeader("Access-Control-Allow-Origin", "http://localhost:3000");
        resp.addHeader("Access-Control-Allow-Origin", "*");
//      resp.addHeader("Access-Control-Allow-Origin", "http://digitran-virtualtestengineer.tk");
        resp.addHeader("Access-Control-Allow-Headers", "*");
        resp.addHeader("Access-Control-Allow-Methods", "*");
        chain.doFilter(request, response);
    }

我的客户端代码是基于 ReactJS 的,API 调用如下:

axios.post("http://localhost:9900/upload/file", data, config )

问题: 每次我必须使用以下代码行在 localhost 和域之间切换:

resp.addHeader("Access-Control-Allow-Origin", "http://localhost:3000");
resp.addHeader("Access-Control-Allow-Origin", "http://digitran-virtualtestengineer.tk");

或者我必须允许所有域如下:

resp.addHeader("Access-Control-Allow-Origin", "*");

问题:

有没有办法像下面的代码一样在同一行添加本地主机和域?

resp.addHeader("Access-Control-Allow-Origin", ["http://digitran-virtualtestengineer.tk", "http://localhost:3000"]);

【问题讨论】:

  • 为什么不将该配置外部化,以便您可以在不同环境中从 env var 进行设置?这可以简化您的代码,并使其更灵活地部署到新环境。
  • 你真的需要Access-Control-Allow-Origin 中的http://digitran-virtualtestengineer.tk 吗?仅当实时站点 HTML 来自与托管实时 API 的域不同的域时,您才需要它。
  • 感谢每一位。我会努力回来的

标签: java reactjs cors jersey


【解决方案1】:

CORS 请求将具有 Origin 标头。此标头询问服务器“是否允许该来源?”服务器回复Access-Control-Allow-Origin: <origin>。您可以使用* 表示允许所有来源,或者您可以使用单个来源,通常是使用Origin 标头请求的来源或仅允许的单个来源。

所以你应该做的是从HttpServletRequest 中获取Origin 标头。然后保留您要允许的来源列表。然后根据列表检查来源,确保来源在列表中。如果是,则将该原点添加为 Access-Control-Allow-Origin 标头的值。类似的东西

// class member
final List<String> allowedOrigins
        = Arrays.asList("http://localhost:3000",
                        "http://digitran-virtualtestengineer.tk");

// in filter method
String origin = request.getHeader("ORIGIN");
if (origin != null) {
    if (allowedOrigins.contains(origin)) {
        response.addHeader("Access-Control-Allow-Origin", origin);
    } else {
        // end request and send 403 Forbidden response
    }
}

另外,正如@jonrsharpe 所提到的,您应该考虑将这些允许的来源添加到配置文件中。您可以从此文件构建列表。这是生产项目中的常见做法。

【讨论】:

【解决方案2】:

最终代码如下:

public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
            String url = null;
            String clientOrigin = null;
            if (request instanceof HttpServletRequest) {
                 url = ((HttpServletRequest)request).getRequestURL().toString();             
                 clientOrigin = ((HttpServletRequest)request).getHeader("origin");
                 System.out.println("url inside doFilter = "+url);
                 System.out.println("clientOrigin inside doFilter = "+clientOrigin);
                }
            HttpServletResponse resp = (HttpServletResponse) response;
            if (clientOrigin != null) {
                if (allowedOrigins.contains(clientOrigin)) {
                    resp.addHeader("Access-Control-Allow-Origin", clientOrigin);
                } 
            }       
    
            resp.addHeader("Access-Control-Allow-Headers", "*");
            resp.addHeader("Access-Control-Allow-Methods", "*");
            chain.doFilter(request, response);
        }

【讨论】:

    猜你喜欢
    • 2020-04-30
    • 2018-07-09
    • 1970-01-01
    • 2016-04-14
    • 2019-11-17
    • 2021-05-12
    • 2019-06-29
    • 2011-01-03
    • 2011-11-12
    相关资源
    最近更新 更多