2017-08-29 43 views
0

我有一个构建在Angular 4和Node.JS上的前端应用程序堆栈,然后调用使用Play Framework构建的后端API。我现在有了CORS过滤器的问题。我已经启用了CORS过滤器上,如下我玩框架:CORS问题与Angular 4应用程序调用Play Framework Web App

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 
     ) 
    } 
    } 
} 

但是,当我把这个端点从我的角度4应用程序,我可以从我的戏框架的服务器日志,它的确是进来作为一个选项,请见要求:

[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客户端我的发挥框架的应用程序,我看到以下内容:

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应用程序中调用相同的终点,但对我来说这很奇怪,却无法做到这一点!

+0

我认为CORS必须首先执行OPTIONS以查看带有返回标头的服务器的功能。由于它正在返回一个404,我猜测在做GET之前会停止请求。也许你有一些标题或内容类型,使它不是一个'简单的请求'? [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS) –

+0

我没有任何特殊的标题!我将使用我在Play Framework中设置的所有标题更新我的文章! – sparkr

+1

还没有使用过播放框架,也许检查[this](https://stackoverflow.com/questions/20525178/http-options-request-gets-completely-ignored-by-play-route-config)了吗?来自您的角度应用程序的东西导致它不是一个简单的请求,因此它发送OPTIONS预检以检查服务器功能,并且您的服务器正在为OPTIONS请求返回404。我想你要么必须弄清楚如何做出简单的请求(通过CORS链接carefilly)或让你的服务器来处理选项... –

回答

0

不确定具体是关于这个问题的,但是如果你有问题请求CORS,那就用这个chrome extension(允许控制允许原点)。

这将让你做,而不需要通过任何额外的参数headers/configCORS请求。

缺点是,它不适用于CORS patch request

+0

看看我更新的帖子! – sparkr

0

所以好像我已经找到了问题。这是我get函数在我的角度应用:

get(path: string, params: URLSearchParams = new URLSearchParams()): Observable<any> { 
    return this.http.get(`${environment.api_url}${path}`, { headers: this.setHeaders(), search: params }) 
     .catch(this.formatErrors) 
     .map((res: Response) => res.json()); 
    } 

这是setHeaders功能:

private setHeaders(): Headers { 
    const headersConfig = { 
     'Content-Type': 'application/json', 
     'Accept': 'application/json', 
     'Access-Control-Allow-Origin': '*', 
     'Access-Control-Request-Headers': 'content-type' 
    }; 

我不得不完全删除这个!所以我现在看起来像:

get(path: string, params: URLSearchParams = new URLSearchParams()): Observable<any> { 
    return this.http.get(`${environment.api_url}${path}`, { search: params }) 
     .catch(this.formatErrors) 
     .map((res: Response) => res.json()); 
    } 

我不确定这是否正确,但确实摆脱了问题!我可以从我的播放服务器看到记录以下:

[info] application - GET /powerPlants?onlyActive=false&page=1 took 1539ms HTTP status >> 200 
[info] application - GET /powerPlants?onlyActive=false&page=1 took 1549ms HTTP status >> 200 
[info] application - GET /powerPlants?onlyActive=false&page=1 took 1607ms HTTP status >> 200 
+0

啊,我认为这是'CORS文档](https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS)的'内容类型'。唯一允许的类型是两个表单或'text/plain'。由于它是一个GET请求,你不需要它,这是你发送的数据的内容类型。 –

相关问题