【问题标题】:How to properly separate frontend and backend?如何正确分离前端和后端?
【发布时间】:2015-03-31 21:32:12
【问题描述】:

我有一个基于 playFramework 的项目。它有很多业务逻辑,涉及actor,不同的解析器,通过API与三个服务一起工作等。前端是用angularJs(单网页应用程序)编写的。我们还使用 coffeScript 和 less,为此我添加了 sbt 插件来编译它们

我觉得完全拥有这些东西是不对的。每当我将提交提交到与 css 文件相关的更改的存储库时,jenkins 都会下载 scala 依赖项、构建项目等。它是仅用于用户体验的静态内容。

当我的前端开发人员需要对后端部分进行一些更改时,他会发疯,因为他对 scala 不够了解。因此,他通过尝试让它工作而以无效的方式花费时间,而我可以在最短的时间内做到这一点。

我认为一个存储库应该用于前端(angular、coffee、less、图像、字体),第二个用于后端。

今天我读了几篇关于这个问题的文章,受到启发,我决定把它们分开一次:)

首先我安装了 node、npm、grunt 和 http-server 然后我为 grunt: less 和 coffee 设置插件。

我在地址上运行了“grunt http-server”:localhost:8282

在地址:localhost:9000 上启动了我的播放应用程序

然后用 'localhost:9000/api/client' 替换旧的 angular $resource url '/api/client' 以检查它是否有效,我将在 localhost:8282 页面上看到客户端列表。但它不起作用。我在 js 控制台中得到了这个:

XMLHttpRequest cannot load localhost:9000/api/client. Origin localhost:8282 is not allowed by Access-Control-Allow-Origin

这是跨域问题,所以我搜索并更改了服务于 /api/client 的控制器

Ok(toJson(res.sortBy(_.id))).withHeaders(("Access-Control-Allow-Origin", "*"))

标题得到正确应用,我在 safari 中检查了这一点。我还配置了角度 $httpProvider

$httpProvider.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest'

但还是不行。

我不擅长设置 http 服务器,但可能有更好的方法吗?可能是要设置一些代理?或者如何设置 nginx?

有什么建议吗?谢谢!

【问题讨论】:

    标签: angularjs playframework gruntjs frontend backend


    【解决方案1】:

    在游戏中设置 CORS 包括两个步骤

    1. 响应预检请求(选项请求)
    2. 设置响应标头。

    您似乎错过了第一步,请查看此article 了解详情。

    【讨论】:

      【解决方案2】:

      感谢 Rebotnix

      你是对的,后端没有响应所需的标头。

      文章中的Scala代码有点过时(Play 2.3.6中没有PlainResult),但它解释了使用CORS的要点。

      package controllers.filters
      
      import play.api.mvc.{Filter, RequestHeader, Result}
      
      import scala.concurrent.ExecutionContext.Implicits.global
      import scala.concurrent.Future
      
      object CorsFilter extends Filter {
      
        override def apply(nextFilter: (RequestHeader) => Future[Result])(rh: RequestHeader): Future[Result] = {
      
          nextFilter(rh).map { result =>
            result.withHeaders(
              "Access-Control-Allow-Origin" -> "*",
              "Access-Control-Allow-Methods" -> "POST, GET, OPTIONS, PUT, DELETE"
            )
          }
      
        }
      
      }
      

      以及全局设置:

      import controllers.filters.CorsFilter
      import play.api.mvc.WithFilters
      
      object Global extends WithFilters(CorsFilter)
      

      和预检动作(与文章中的一样)

      def preflight(url: String) = Action {
          Ok.withHeaders(
            "Access-Control-Allow-Origin" -> "*",
            "Access-Control-Allow-Headers" -> "Origin, X-Requested-With, Content-Type, Accept, Referer, User-Agent",
            "Access-Control-Allow-Methods" -> "POST, GET, PUT, DELETE, OPTIONS",
            "Allow" -> "*"
          )
        }
      

      并为预检设置路线:

      OPTIONS        /*anyUrl                                                 controllers.Application.preflight(anyUrl:String)
      

      现在一切正常!

      【讨论】:

      • 如果对您有帮助,您可能希望接受我的回答。然后遇到类似问题的其他人可以知道如何调试自己的代码逻辑。谢谢:)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-05
      • 1970-01-01
      • 2017-08-01
      • 2016-07-02
      • 1970-01-01
      相关资源
      最近更新 更多