CORS问题与Angular 4应用程序调用Play Framework Web App
我有一个构建在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应用程序中调用相同的终点,但对我来说这很奇怪,却无法做到这一点!
不确定具体是关于这个问题的,但是如果你有问题请求CORS
,那就用这个chrome extension(允许控制允许原点)。
这将让你做,而不需要通过任何额外的参数headers/config
CORS
请求。
缺点是,它不适用于
CORS patch request
。
看看我更新的帖子! – sparkr
所以好像我已经找到了问题。这是我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
啊,我认为这是'CORS文档](https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS)的'内容类型'。唯一允许的类型是两个表单或'text/plain'。由于它是一个GET请求,你不需要它,这是你发送的数据的内容类型。 –
你知道Play提供内置的CORS在过滤器的形式处理?有关详细信息,请参阅https://www.playframework.com/documentation/2.6.x/CorsFilter。
这减轻了手动处理CORS的负担。
我认为CORS必须首先执行OPTIONS以查看带有返回标头的服务器的功能。由于它正在返回一个404,我猜测在做GET之前会停止请求。也许你有一些标题或内容类型,使它不是一个'简单的请求'? [CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS) –
我没有任何特殊的标题!我将使用我在Play Framework中设置的所有标题更新我的文章! – sparkr
还没有使用过播放框架,也许检查[this](https://stackoverflow.com/questions/20525178/http-options-request-gets-completely-ignored-by-play-route-config)了吗?来自您的角度应用程序的东西导致它不是一个简单的请求,因此它发送OPTIONS预检以检查服务器功能,并且您的服务器正在为OPTIONS请求返回404。我想你要么必须弄清楚如何做出简单的请求(通过CORS链接carefilly)或让你的服务器来处理选项... –