在Play Framework 2.4.x中解决CORS问题

时间:2015-08-12 21:08:33

标签: java playframework cors playframework-2.4

我有一个提供JSON / HTTP API的java play framework 2.4.x Web应用程序。当我运行我的前端HTML / JS file:///Users/nize/tmp/index.htmlhttp://localhost:9000 chrome show上调用API时

XMLHttpRequest cannot load http://localhost:9000. 
No 'Access-Control-Allow-Origin' header is present 
on the requested resource. Origin 'null' is therefore 
not allowed access. The response had HTTP status code 403.

我已按照Play Framework 2.4.x CORS Documentation中的说明配置了网络应用程序:

  • 更新至build.sbt
  • 将类Filters.java添加到项目的根目录(也尝试/app
  • 将以下节添加到application.conf

    play.filters.cors {   allowedOrigins = [“*”,“http://localhost”]   #allowedHttpMethods = [“GET”,“POST”]   #allowedHttpHeaders = [“接受”]   #preflightMaxAge = 3天 }

我错过了什么?

修改 症状与Other very similar stackoverflow post看起来相同或相似。通过重新配置计算机上安装的Cisco AnyConnect VPN解决了该问题。但是,我没有安装该软件。

7 个答案:

答案 0 :(得分:14)

首先在conf / application.conf中添加/编辑这些行(配置)

 play.filters.cors {
  # allow all paths
  pathPrefixes = ["/"]
  # allow all origins (You can specify if you want)
  allowedOrigins = null
  allowedHttpMethods = ["GET", "POST", "PUT", "DELETE"]
  # allow all headers
  allowedHttpHeaders = null
 }   

(请注意,以'#'开头的行是注释行。)

然后转到build.sbt并添加此行。

libraryDependencies += filters

最后创建一个名为' Filters.java'的Java类。并将其包含在根目录(/ app)中。

import play.api.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 };
    }
}

您可以参考official documentation了解更多信息。

答案 1 :(得分:7)

我在遵循相同的文档时遇到了同样的问题。

问题在于您使用过的CORS过滤器:

allowedOrigins = ["*","http://localhost"]

如果您想允许所有来源使用:

allowedOrigins = null

allowedHttpMethods

采用相同的方法

根据documentation

引用:

  

允许的起源。如果为null,则允许所有原点。

allowedOrigins = null

希望这有帮助!

答案 2 :(得分:3)

我认为CORS filter in Play不起作用!我一步步跟进,但不知怎的,我总是在Ajax调用中在浏览器(Chrome和Firefox)中获得HTTP-403。问题是我甚至没有在服务器端获得堆栈跟踪。我认为CORS过滤器中的DefaultHttpErrorHandler以某种方式吞噬了它。在响应“Access-Control-Allow-Origin”标题丢失,所以我只是手动添加。

class Filters @Inject() (corsFilter: CORSFilter, log: LoggingFilter) extends HttpFilters {
  def filters = {
    // CORS filter does not work
    //Seq(corsFilter, log)
    Seq(log)
  }
}

这是日志过滤器(Credit:Play!framework)

class LoggingFilter extends Filter {

  def apply(nextFilter: RequestHeader => Future[Result])(requestHeader: RequestHeader): Future[Result] = {

    val startTime = System.currentTimeMillis

    nextFilter(requestHeader).map { result =>

      val endTime = System.currentTimeMillis
      val requestTime = endTime - startTime

      Logger.info(s"${requestHeader.method} ${requestHeader.uri} " +
        s"took ${requestTime}ms and returned ${result.header.status}")

      result.withHeaders(
        "Request-Time" -> requestTime.toString,
        "Access-Control-Allow-Origin" -> "*"   // Added this header
      )
    }
  }
}

答案 3 :(得分:1)

我遇到了类似的问题,我的请求是403。我通过删除:

解决了这个问题
echo $this->Form->input('day_of_week',array(
                'type' => 'select', 
                'multiple' => 'checkbox', 
                'options' => $daysOfWeek));

他们在示例配置中使用它们。然而,我仍然不清楚它的安全含义是什么,所以YMMV。

答案 4 :(得分:0)

在Firefox中有效吗? Chrome对从本地文件运行Ajax有一些限制,例如,请参阅this link。如果它是特定于Chrome的,您可以使用命令行开关启动Chrome以删除限制。

答案 5 :(得分:0)

这可能无法解决海报的问题,但是当我遇到相同的症状时它解决了我的问题,并且我发布它以防它可以在相同的情况下帮助其他人。

我实际上误解了CORS是如何工作的。我有两个独立的Play应用程序,一个带有REST API,另一个带有使用REST API的Web界面。我按照问题中提到的文档页面中的说明进行操作,但我的错误是我在Web界面应用程序中执行了此操作。当我在REST API应用程序上执行此操作时,它立即起作用。

答案 6 :(得分:0)

filters = "filters.Filters"


play.filters {

  cors {

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

    # The allowed HTTP methods. If null, all methods are allowed
    allowedHttpMethods = null

    # The allowed HTTP headers. If null, all  headers are allowed.
    allowedHttpHeaders = null
  }

}



public class Filters implements HttpFilters {

    @Inject
    private CORSFilter corsFilter;

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

}