CORS с Akka-Http и Spray

Я пытаюсь отправить http-запросы из локального файла (клиента) на мой внутренний сервер.

После прочтения бесчисленных статей о том, как включить CROS (обмен ресурсами между источниками), я все еще получаю сообщение об ошибке: "Ответ на предварительный запрос не проходит проверку контроля доступа: Нет 'Access-Control-Allow Заголовок -Origin присутствует в запрошенном ресурсе. Следовательно, источник 'null' не имеет доступа. Ответ имеет код состояния HTTP 405."

Для моего внутреннего сервера я использую Akka-Http и Spray-Json. В итоге я решил использовать akka-http-cors (https://github.com/lomigmegard/akka-http-cors), но и это не решило проблему. Я понимаю, что мне следует использовать директиву options и «Access-Control-Allow-Origin» (имя файла), но я не могу понять, как их правильно использовать.

Я приложил фрагменты моего бэкэнда и кода javascript. Если кто-нибудь знает, как правильно включить CROS между моим клиентом и сервером, это было бы потрясающе.

Внутренний код scala-akka-spray

var signInUrl = 'http://0.0.0.0:8080/user/sign-in';

function sendEntry(form, signType) {
  var jsonString = serializeEntry(form);
  
  var httpRequest = new XMLHttpRequest();
  httpRequest.open('POST', signInUrl, true); // true meanining asynchronous
  httpRequest.setRequestHeader('Content-type', 'application/json');
  httpRequest.send(jsonString);
}


person David Deborin    schedule 30.07.2018    source источник


Ответы (2)


Мне удалось заставить это работать с помощью кода, указанного на https://dzone.com/articles/handling-cors-in-akka-http

Скопировано здесь для завершения:

import akka.http.scaladsl.model.HttpMethods._
import akka.http.scaladsl.model.headers._
import akka.http.scaladsl.model.{HttpResponse, StatusCodes}
import akka.http.scaladsl.server.Directives._
import akka.http.scaladsl.server.directives.RouteDirectives.complete
import akka.http.scaladsl.server.{Directive0, Route}

import scala.concurrent.duration._


/**
  * From https://dzone.com/articles/handling-cors-in-akka-http
  *
  *
  */
trait CORSHandler {

  private val corsResponseHeaders = List(
    `Access-Control-Allow-Origin`.*,
    `Access-Control-Allow-Credentials`(true),
    `Access-Control-Allow-Headers`("Authorization",
      "Content-Type", "X-Requested-With"),
    `Access-Control-Max-Age`(1.day.toMillis)//Tell browser to cache OPTIONS requests
  )
  //this directive adds access control headers to normal responses
  private def addAccessControlHeaders: Directive0 = {
    respondWithHeaders(corsResponseHeaders)
  }
  //this handles preflight OPTIONS requests.
  private def preflightRequestHandler: Route = options {
    complete(HttpResponse(StatusCodes.OK).
             withHeaders(`Access-Control-Allow-Methods`(OPTIONS, POST, PUT, GET, DELETE)))
  }
  // Wrap the Route with this method to enable adding of CORS headers
  def corsHandler(r: Route): Route = addAccessControlHeaders {
    preflightRequestHandler ~ r
  }
  // Helper method to add CORS headers to HttpResponse
  // preventing duplication of CORS headers across code
  def addCORSHeaders(response: HttpResponse):HttpResponse =
    response.withHeaders(corsResponseHeaders)
}

Используя его как:

private val cors = new CORSHandler {}

val foo: Route = path("foo") {
    //Necessary to let the browser make OPTIONS requests as it likes to do 
    options {
      cors.corsHandler(complete(StatusCodes.OK))
    } ~ post( cors.corsHandler(complete("in foo request")) )
  }

Подробнее: https://ali.actor/enabling-cors-in-akka-http/

person Ali    schedule 28.04.2019

Может быть полезно для кого-то: я только что добавил директиву cors(), и это помогло мне:

import ch.megard.akka.http.cors.scaladsl.CorsDirectives.cors

val route: Route = cors() {    // cors() may take optional CorsSettings object
  get {...}
}
person Mitrakov Artem    schedule 10.02.2021