【发布时间】:2018-02-07 08:18:01
【问题描述】:
我有一个基于 Angular 4 和 Node.JS 的前端应用程序堆栈,然后调用使用 Play Framework 构建的后端 API。我现在遇到了 CORS 过滤器的问题。我在 Play 框架上启用了 CORS 过滤器,如下所示:
object MyController extends Controller {
implicit class RichResult (result: Result) {
def enableCors = result.withHeaders(
"Access-Control-Allow-Origin" -> "*"
, "Access-Control-Allow-Methods" -> "OPTIONS, GET, POST, PUT, DELETE, HEAD" // OPTIONS for pre-flight
, "Access-Control-Allow-Headers" -> "Accept, Content-Type, Origin, X-Json, X-Prototype-Version, X-Requested-With" //, "X-My-NonStd-Option"
, "Access-Control-Allow-Credentials" -> "true"
)
}
def powerPlantDetails(id: Int) = Action.async {
dbService.powerPlantById(id).flatMap {
case None =>
Future.successful(
NotFound(s"HTTP 404 :: PowerPlant with ID $id not found").enableCors
)
case Some(powerPlantRow) =>
Future.successful(
Ok(Json.prettyPrint(
Json.toJson(toPowerPlantConfig(powerPlantRow)))
).enableCors
)
}
}
}
但是当我从 Angular 4 应用程序调用此端点时,我可以从 Play Framework 的服务器日志中看到它确实是作为 OPTIONS 请求进入的:
[info] application - OPTIONS /powerPlants?onlyActive=false&page=1 took 0ms HTTP status >> 404
[info] application - OPTIONS /powerPlants?onlyActive=false&page=1 took 0ms HTTP status >> 404
这是为什么?我如何确保我的 Angular 4 应用正在执行 GET 而不是 OPTIONS?
编辑:如果我从 Chrome 中的高级 REST 客户端调用我的 Play Framework 应用程序,我会看到以下内容:
application - GET /powerPlants?onlyActive=false&page=1 took 25694ms HTTP status >> 200
(Access-Control-Allow-Origin,*)
(Access-Control-Allow-Headers,Accept, Content-Type, Origin, X-Json, X-Prototype-Version, X-Requested-With)
(Access-Control-Allow-Methods,OPTIONS, GET, POST, PUT, DELETE, HEAD)
(Access-Control-Allow-Credentials,true)
可以看出它实际上是在发出 GET 请求,但如果我从我的 Angular 应用程序调用相同的端点,它就无法做到这一点,这对我来说很奇怪!
【问题讨论】:
-
我认为 CORS 必须先执行一个 OPTIONS 才能查看服务器的功能以及返回的标头。由于它返回 404,我猜想在执行 GET 之前停止请求。也许您有一些标题或内容类型使其不是“简单请求”? CORS
-
我没有任何特殊的标题!我将使用我在 Play Framework 中设置的所有标题更新我的帖子!
-
没用过play框架,看看this吧?您的 Angular 应用程序中的某些内容导致它不是一个简单的请求,因此它正在发送 OPTIONS 预检以检查服务器功能,并且您的服务器正在为 OPTIONS 请求返回 404。我认为您要么必须弄清楚如何使其成为简单的请求(小心地通过该 CORS 链接),要么让您的服务器处理 OPTIONS...
-
让我的 Play 服务器处理 GET 请求的 OPTIONS 是我将避免的事情。我还有另一个 Angular 应用程序正在向我的 Play 服务器中的同一端点发出请求,并且正在通过,但是这个新的 Angular 应用程序似乎有问题!
-
然而,两者之间的唯一区别是,在新的 Angular 应用程序中,当我执行 http.get(...) 时,我设置了一些标题。也许我会尝试删除它们并试一试!
标签: angular http typescript playframework cors