【问题标题】:Play CORS not working播放 CORS 不工作
【发布时间】:2017-10-12 10:43:28
【问题描述】:

我已经在本地部署了我的 Play 应用程序,并且在我的浏览器中通过 localhost:9000 访问我的 REST API 运行良好。

但是,从file:///C:/Users/XXX/XXX//index.html 执行 jQuery 脚本(见下文)时出现以下错误:

Failed to load resource: the server responded with a status of 403 (Forbidden)

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.

我按照https://www.playframework.com/documentation/2.6.x/CorsFilter 下的说明进行操作。

我的build.sbt

libraryDependencies ++= Seq(
  jdbc,
  evolutions,
  guice,
  "com.h2database" % "h2" % "1.4.194",
  javaJpa,
  "org.hibernate" % "hibernate-core" % "5.2.5.Final",
  filters
)

我的application.conf

play.filters.enabled += "play.filters.cors.CORSFilter"   

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
 }   

注意:我尝试了 allowedOrigins = nullallowedOrigins = ["*"]

jQuery 脚本:

$.ajax({

    'url' : 'http://localhost:9000/employee/' + user_id + '/weeklyWorkingHours',
    'type' : 'GET',
    'success' : function(data) {
        console.log('Data: '+ JSON.stringify(data));

    },
    'error' : function(request,error)
    {
        console.log("Error: "+JSON.stringify(request));
    }
});

Play 是这样说的:

[warn] p.f.c.CORSFilter - Invalid CORS request;Origin=Some(null);Method=GET;Access-Control-Request-Headers=None

【问题讨论】:

  • 播放规范说by default all origins are allowed。您提到您尝试了allowedOrigins = nullallowedOrigins = ["*"]。你试过删除它吗?
  • 感谢您的提示。不幸的是,它不能解决问题。
  • 我认为问题出在Origin=Some(null)。 Play 会将其验证为isValidOrigin = new URI("null").getScheme ne null。返回错误。您可以尝试使用有效的Origin 来执行请求吗?这是Origin = <some valid url>?

标签: playframework playframework-2.6


【解决方案1】:

您将无法通过本地文件使 CORS 工作。浏览器向服务器发送一个值为 null 的 origin 标头,Play 不会以 access-control-allow-origin 标头响应。为了进行测试,您可以设置本地 Web 服务器,例如使用

cd c:\Users\XXX\XXX
python -m SimpleHTTPServer

然后您可以将文件加载为

http://localhost:8000/index.html

【讨论】:

  • 感谢您的回答。难道不能以同样接受空值的方式配置 Play 吗?我认为 CORS 仍然无法正常工作,因为使用 CORS (chrome.google.com/webstore/detail/allow-control-allow-origi/…) 的 chrome 插件,我可以从本地文件调用 localhost。
  • 我还没有找到像这样配置 Play 的方法,并且我阅读了足够多的源代码,我认为没有相关规定。该扩展不会修改 origin 标头,因此您不会对 Play 感到满意。请务必使用开发工具监视该标头。尝试本地网络服务器。
【解决方案2】:

尝试将它放在 application.conf 中(它将允许所有来源)

play.filters.cors.allowedOrigins = null

并且不要禁用 cors 过滤器

play.filters.enabled += "play.filters.cors.CORSFilter"

【讨论】:

  • 不幸的是它没有解决问题。无论如何,谢谢!
  • 好吧 play.filters.cors.allowedOrigins = ["localhost:9000"]
  • 也不起作用,因为我正在从不同的域访问我的 REST 服务
  • 只需填写不同的域 play.filters.cors.allowedOrigins = ["localhost:9000" , "domain2.com", "domain3.com"]
  • 没有办法接受所有域吗?在我的项目设置中,我无法做到这一点。
【解决方案3】:

因为我在这方面花了太多时间,所以这是 Java for Play 2.12 中的答案:

  1. 在 app\filters\CorsFilter.java 中:

    package filters;
    
    import java.util.concurrent.CompletionStage;
    import java.util.function.Function;
    
    import com.google.inject.Inject;
    import com.google.inject.Singleton;
    
    import akka.stream.Materializer;
    import play.mvc.Filter;
    import play.mvc.Http.RequestHeader;
    import play.mvc.Result;
    
    
    
    @Singleton
    public class CorsFilter extends Filter {
    
        @Inject
        public CorsFilter(Materializer mat) {
         super(mat);
        }
    
        @Override
        public CompletionStage<Result> apply(Function<RequestHeader, CompletionStage<Result>> next, RequestHeader rh) {
    
         return next.apply(rh).thenApply(result ->
             {
                 return result.withHeaders(
                         "Access-Control-Allow-Origin" , "*",
                         "Access-Control-Allow-Methods" , "OPTIONS, GET, POST, PUT, DELETE, HEAD",
                         "Access-Control-Allow-Headers" , "Accept, Content-Type, Origin, X-Json, X-Prototype-Version, X-Requested-With",
                         "Access-Control-Allow-Credentials" , "true"
                     );
             });
        }
    

    }

  2. 在您的 conf\application.conf 中,在某处添加以下行:

    play.filters.enabled += filters.CorsFilter
    
  3. 在您的 conf\routes 中,添加以下内容:

    OPTIONS    /          controllers.OptionsController.options(path: String ?= "")
    OPTIONS    /*path     controllers.OptionsController.options(path)
    
  4. 添加类 controllers.OptionsController(在 app\controllers\OptionsController.java 中):

    package controllers;
    
    import play.mvc.Controller;
    import play.mvc.Result;
    
    public class OptionsController extends Controller {
    
     public Result options(String path) {
    
         return ok("").withHeaders(
                   "Access-Control-Allow-Origin" , "*",
                   "Access-Control-Allow-Methods" , "GET, POST, PUT, DELETE, OPTIONS",
                   "Access-Control-Allow-Headers" , "Accept, Origin, Content-type, X-Json, X-Prototype-Version, X-Requested-With",
                   "Access-Control-Allow-Credentials" , "true",
                   "Access-Control-Max-Age" , Integer.toString(60 * 60 * 24)
         );
     }
    }
    

【讨论】:

    猜你喜欢
    • 2016-02-22
    • 2017-08-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多