我有一个基于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应用程序中调用相同的终点,那么它就不能这样做了,这对我来说很奇怪!
答案 0 :(得分:0)
不确定此问题,但如果您在提出CORS
请求时遇到问题,请使用此chrome extension(允许控制允许来源)。
这样,您无需在headers/config
中传递任何额外参数即可发出CORS patch request
请求。
的缺点是,它不适用于
Container container = new Container(new BorderLayout()); Media video = com.codename1.media.MediaManager.createMedia(url, true); // url is the url above video.setNativePlayerMode(true); MediaPlayer mp = new MediaPlayer(video); //place the media player in the container container.add(BorderLayout.CENTER, mp); Component component = Container.encloseIn(new FlowLayout(Container.RIGHT), container);
。
答案 1 :(得分:0)
好像我已经弄明白了这个问题。这是我的Angular应用程序中的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());
}
我不确定这是否正确,但确实摆脱了问题!我可以从我的Play服务器日志中看到以下内容:
[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
答案 2 :(得分:0)
您是否知道Play以过滤器的形式提供内置CORS处理?有关详细信息,请参阅https://www.playframework.com/documentation/2.6.x/CorsFilter。
这消除了手动处理CORS的负担。