如何正确分离前后端?

How to properly separate frontend and backend?

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

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

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

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

今天看了几篇关于这个问题的文章,受到启发,决定一劳永逸地把它们分开:)

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

I 运行 'grunt http-server' 地址:localhost:8282

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

然后将旧的 angular $resource url '/api/client' 替换为 'localhost:9000/api/client' 以检查它是否有效,我将在 [=45= 页上看到客户列表].但它不起作用。我在 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", "*"))

Headers 得到正确应用,我在 safari 中检查过这个。我还配置了 angular $httpProvider

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

但是还是不行

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

有什么建议吗?谢谢!

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

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

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

感谢 Rebotnix

你是对的,后端没有响应需要 headers。

文章中的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)

现在一切正常!