如何正确分离前后端?
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 包括两个步骤
- 响应预检请求(选项请求)
- 设置 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)
现在一切正常!
我有一个基于 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 包括两个步骤
- 响应预检请求(选项请求)
- 设置 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)
现在一切正常!