我正在尝试构建一个同构应用程序,其中ReactJS作为我的前端应用程序服务器,使用express和Play框架作为我在Scala中的后端技术。
我面临的问题是我从ReactJS进行ajax调用以点击Play提供的web服务。我的GET请求运行良好,但我无法POST数据,我收到以下错误:
XMLHttpRequest无法加载http://localhost:7050/login。请求的资源上不存在“Access-Control-Allow-Origin”标头。因此,不允许原点“http://localhost:3000”访问。响应的HTTP状态代码为400。
我知道Ajax调用跨域(CORS),但我无法在播放服务器端正确配置。
我在build.sbt中的依赖项中添加了过滤器库:
libraryDependencies + = filters
这两条路由允许我配置OPTIONS HTTP请求:
OPTIONS / controllers.Application.options(path =“”)
OPTIONS / * path controllers.Application.options(path)
我的全球对象如下:
object Global extends WithFilters(CorsFilter) {
// called when a route is found, but it was not possible to bind the request parameters
override def onBadRequest (request: RequestHeader, error: String) = Future.successful(
BadRequest("Bad Request: " + error)
)
}
object CorsFilter extends Filter {
def apply (nextFilter: (RequestHeader) => Future[Result])(requestHeader: RequestHeader): Future[Result] = {
nextFilter(requestHeader).map { result =>
result.withHeaders(HeaderNames.ACCESS_CONTROL_ALLOW_ORIGIN -> "*",
HeaderNames.ALLOW -> "*",
HeaderNames.ACCESS_CONTROL_ALLOW_METHODS -> "POST, GET, PUT, DELETE, OPTIONS",
HeaderNames.ACCESS_CONTROL_ALLOW_HEADERS -> "Origin, X-Requested-With, Content-Type, Accept, Referer, User-Agent"
)
}
}
}
在控制器端,我正在配置OPTIONS请求,如下所示:
def options(path: String) = CorsAction {
Action { request =>
Ok.withHeaders("Access-Control-Allow-Origin" -> "*",
"Allow" -> "*",
"Access-Control-Allow-Methods" -> "POST, GET, PUT, DELETE, OPTIONS",
"Access-Control-Allow-Headers" -> "Origin, X-Requested-With, Content-Type, Accept, Referer, User-Agent")
}
}
处理HTTP请求的Action如下:
// Adds the CORS header
case class CorsAction[A](action: Action[A]) extends Action[A] {
def apply(request: Request[A]): Future[Result] = {
action(request).map(result => result.withHeaders(HeaderNames.ACCESS_CONTROL_ALLOW_ORIGIN -> "*",
HeaderNames.ALLOW -> "*",
HeaderNames.ACCESS_CONTROL_ALLOW_METHODS -> "POST, GET, PUT, DELETE, OPTIONS",
HeaderNames.ACCESS_CONTROL_ALLOW_HEADERS -> "Origin, X-Requested-With, Content-Type, Accept, Referer, User-Agent"
))
}
lazy val parser = action.parser
}
最后,我的AJAX调用将完成:
$.ajax({
url: "http://localhost:7050/users",
dataType: 'json',
type: 'POST',
contentType: 'application/json',
crossDomain: true,
data: {"email": this.state.email, "pwd": md5(this.state.pwd)},
success: function(data) {
this.setState({user: data});
}.bind(this),
error: function(xhr, status, err) {
console.error("POST users", status, err.toString());
}.bind(this)
});
我在Play工作的版本是2.3.8。
非常感谢您提前帮助我解决这个问题。
祝大家圣诞快乐。
此致