在两个独立的 运行 个本地应用程序中使用 cors

Using cors across two independently running local apps

我有两个独立的应用程序 运行,一个负责我的后端(用 Scala Play 编写),另一个是我的前端(Angular 使用静态节点服务器)。

我尝试通过我的 Scala Play 应用程序中的表单在我的前端请求数据。

this.insertionOrder = function(){
          $http({
            method: 'POST',
            url: '//localhost:9000/insertsupplier',
            header: {
              'Content-type': 'application/json',
              'Access-Control-Allow-Origin' : '*',
              'Access-Control-Allow-Methods' : 'POST, GET, OPTIONS'
            },
            data:{
              'supplier_id': 1,
              'suppliername': 'xxx',
              'supplier_address': 'xxx xxx xxx xxx',
              'contact': 'xxx@xxx.com',
              'datecreated': '2017-10-15T09:45:00.000UTC+00:00'
            }
          }).then(function(response){
            console.log(response);
            return response.data
          }, function(err){
            console.log(err)
          });
        };

我的播放应用程序如下所示:

控制器:

  def insertsupplier = Action(parse.json) { implicit request =>
    val json = request.body
    val sup: Supplier = json.as[Supplier]
    sup.insertSql(con)
    Ok("test")
  }

我的 build.sbt 包含过滤器:

libraryDependencies ++= Seq(
  cache ,
  ws,
  jdbc,
  filters
)

和MyFilters.scala

class MyFilters (implicit inj:Injector)  extends HttpFilters with Injectable {
  implicit val as = inject[ActorSystem]
  implicit val mat = ActorMaterializer()
  val gzip = new GzipFilter()
  val csrf = inject[CSRFFilter]
  val cors = inject[CORSFilter]
  //println(s"csrf: ${csrf.tokenProvider}")
  //println(s"csrf: ${csrf.tokenProvider.generateToken}")
  def filters = Seq(gzip,cors,csrf)
}

最后是我的 application.conf

play.filters.cors {
  pathPrefixes = ["*"]
  allowedOrigins = ["http://localhost:3000","https://localhost:3000","http://localhost:3000/*","https://localhost:3000/*"]
  allowedHttpMethods = ["GET", "POST", "OPTIONS"]
  allowedHttpHeaders = ["Accept"]
 # preflightMaxAge = 1 hour
}

play.filters.csrf {
  cookie.name = "XSRF-TOKEN"
  header.name = "X-XSRF-TOKEN"
}

play.http.filters = "filters.MyFilters"

我一直收到错误 "XMLHttpRequest cannot load http://localhost:9000/insertsupplier. Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access. The response had HTTP status code 500."

我觉得首先我的 CORS 设置是错误的 --> 需要更改什么? 我是新手。

我什至可以使用 cors 从本地主机访问数据吗?

可能您的 CORS 设置没有任何问题,因为错误消息的“响应具有 HTTP 状态代码 500” 部分表明实际立即问题是对服务器的 OPTIONS 请求导致服务器端出现意外故障。

仅从问题中的代码片段来看,无法判断是什么原因导致服务器端出现 500 错误。它可能与您的 CORS 配置完全无关。

但无论如何,您应该删除前端代码中添加 header 'Access-Control-Allow-Origin' : '*''Access-Control-Allow-Methods' 的部分。那些 headers 是 response headers 必须从服务器端发送,而不是从前端代码发送。

但是您的前端代码的 'Content-type': 'application/json' 部分是有效的,并且假设为了从服务器获得预期的响应,它实际上是必需的,如果不触发浏览器做 a CORS preflight OPTIONS request.

但是如果 CORS 预检 OPTIONS 请求失败,浏览器永远不会尝试您的代码实际尝试发送的 POST 请求。如果您的后端以 500 响应响应 OPTIONS 请求,则预检失败。它必须改为响应 200 或 204。