2017-08-29 79 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請求,你不需要它,這是你發送的數據的內容類型。 –