如何在 play-framework 2 中实现跨源资源共享 (CORS)5.x

How to impliment Cross-Origin Resource Sharing ( CORS ) in play-framework 2.5.x

我试图通过使用 Angularjs-1 应用程序从 localhost 中点击 Restful URL 来 获取 json 数据.

我遇到了这个错误

http://localhost:9000/mlm/user/all Failed to load resource: 
the server responded with a status of 404 (Not Found)

index.html:1 XMLHttpRequest cannot load http://localhost:9000/mlm/user/all. 

Response to preflight request doesn't pass access control check:
No 'Access-Control-Allow-Origin' header is present on the requested resource.

Origin 'http://localhost:63342' is therefore not allowed access. 

The response had HTTP status code 404.

我正在使用 play-framework 2.5.4 (java).

编辑 1:将 CORS 设置添加到 app.conf

    play.filters {
    cors {
    # Filter paths by a whitelist of path prefixes
    pathPrefixes = ["/"]

    # The allowed origins. If null, all origins are allowed.
    allowedOrigins = null

    # The allowed HTTP methods. If null, all methods are allowed
    allowedHttpMethods = ["GET", "POST"]

    allowedHttpHeaders = ["Accept"]
    preflightMaxAge = 3 days
  }
}

我认为你必须在你的服务器中放置一个 CORS 允许 header:

response.setHeader("Access-Control-Allow-Origin", "*");//cross domain request/CORS

不知道您使用的是什么框架,但您应该可以在某个地方访问响应 object,然后编写类似这样的内容。

此外,大多数客户端在发出实际请求之前都会执行 http OPTIONS 请求,以检查支持的选项和对服务器的访问。如果您看到 http 方法是 OPTIONS,则不必处理完整的请求。只需写出 headers 并关闭套接字/连接。

非常documented

可以从 application.conf 配置过滤器。例如:

play.filters.cors {
  pathPrefixes = ["/some/path", ...]
  allowedOrigins = ["http://www.example.com", ...]
  allowedHttpMethods = ["GET", "POST"]
  allowedHttpHeaders = ["Accept"]
  preflightMaxAge = 3 days
}



play.filters {
    cors {
    # Filter paths by a whitelist of path prefixes
    pathPrefixes = ["/"]

    # The allowed origins. If null, all origins are allowed.
    allowedOrigins = null

    # The allowed HTTP methods. If null, all methods are allowed
    allowedHttpMethods = ["GET", "POST", "OPTIONS"]

    preflightMaxAge = 3 days
  }
}

终于对我有用了

根据 official 文档

Filter.java 是( 无效):

import play.mvc.EssentialFilter;
import play.filters.cors.CORSFilter;
import play.http.DefaultHttpFilters;

import javax.inject.Inject;

public class Filters extends DefaultHttpFilters {
    @Inject public Filters(CORSFilter corsFilter) {
        super(corsFilter);
    }
}

但它奏效了。 有效的是:

Filter.java(有效)

import play.mvc.EssentialFilter;
import play.filters.cors.CORSFilter;
import play.http.HttpFilters;
import javax.inject.Inject;

public class Filters implements HttpFilters {

    @Inject
    CORSFilter corsFilter;

    public EssentialFilter[] filters() {
        return new EssentialFilter[] { corsFilter.asJava() };
    }
}

感谢 this 回答,关于堆栈溢出的类似问题。

但是为什么官方 docs 的 Filter.java 代码 for 2.5.x 不起作用是百万美元的问题?

似乎是转换为 DefaultHttpFilters.java 的框架中的错误 https://github.com/playframework/playframework/pull/6238

确保遵循本指南:https://www.playframework.com/documentation/2.5.x/CorsFilter

但不要使用 DefaultHttpFilters 的默认实现,而是使用以下内容:

package filters;
import play.http.*;

import java.util.Arrays;

import play.mvc.EssentialFilter;

/**
 * Helper class which has a varargs constructor taking the filters. Reduces boilerplate for defining HttpFilters.
 */
public class MyDefaultHttpFilters implements HttpFilters {

  private final EssentialFilter[] filters;

  public MyDefaultHttpFilters(play.api.mvc.EssentialFilter... filters) {
    this.filters = Arrays.stream(filters).map(f -> f.asJava()).toArray(EssentialFilter[]::new);
  }

  @Override
  public EssentialFilter[] filters() {
    return filters;
  }
}

您的过滤器 class 将必须如下所示:

import javax.inject.*;
import play.mvc.EssentialFilter;
import play.filters.cors.CORSFilter;
import filters.MyDefaultHttpFilters;

public class Filters extends MyDefaultHttpFilters {
    @Inject public Filters(CORSFilter corsFilter) {
        super(corsFilter);
    }
}