Tengo una Play 2.0.1 aplicación que quiero llamar utilizando Javascript alojado en otros dominios. Mi llamada de Javascript está fallando con:

Origin http://mydomain.com is not allowed by Access-Control-Allow-Origin.

He encontrado una serie de ejemplos de cómo establecer la correcta encabezado HTTP en el Juego 1, pero no he encontrado nada para Jugar 2.0.1. Después de la lectura de la documentación (http://www.playframework.org/documentation/2.0.2/JavaResponse) he probado el siguiente, sólo para obtener cosas de trabajo:

public static Result myJsonWebService() {
  ...
  response().setHeader("Access-Control-Allow-Origin", "*");
  return ok(toJson(jsonObject));
}

pero mi JS llamada de servicio web sigue fallando.

¿Qué tengo que hacer para conseguir este trabajo?

OriginalEl autor mstreffo | 2013-01-20

4 Comentarios

  1. 14

    Sólo para Scala, chicos, esta es la aplicación que estoy utilizando actualmente:

    import play.api.mvc._
    import scala.concurrent._
    import play.api.http.HeaderNames._
    
    /**
     * Action decorator that provide CORS support
     *
     * @author Giovanni Costagliola, Nick McCready
     */
    case class WithCors(httpVerbs: String*)(action: EssentialAction) extends EssentialAction with Results {
        def apply(request: RequestHeader) = {
            implicit val executionContext: ExecutionContext = play.api.libs.concurrent.Execution.defaultContext
            val origin = request.headers.get(ORIGIN).getOrElse("*")
            if (request.method == "OPTIONS") { //preflight
                val corsAction = Action {
                    request =>
                        Ok("").withHeaders(
                            ACCESS_CONTROL_ALLOW_ORIGIN -> origin,
                            ACCESS_CONTROL_ALLOW_METHODS -> (httpVerbs.toSet + "OPTIONS").mkString(", "),
                            ACCESS_CONTROL_MAX_AGE -> "3600",
                            ACCESS_CONTROL_ALLOW_HEADERS ->  s"$ORIGIN, X-Requested-With, $CONTENT_TYPE, $ACCEPT, $AUTHORIZATION, X-Auth-Token",
                            ACCESS_CONTROL_ALLOW_CREDENTIALS -> "true")
                }
                corsAction(request)
            } else { //actual request
                action(request).map(res => res.withHeaders(
                    ACCESS_CONTROL_ALLOW_ORIGIN -> origin,
                    ACCESS_CONTROL_ALLOW_CREDENTIALS -> "true"
                ))
            }
        }
    }

    Para usarlo decorar su acción en la siguiente forma:

    def myAction = WithCors("GET", "POST") {
      Action { request =>
        ???
      }
    }
    Yo quería mejorar su respuesta en su sitio web. Pero no puedo iniciar sesión.
    Gracias Nick, he integrado tus mejoras

    OriginalEl autor Lord of the Goo

  2. 11

    Aquí está una cierta información de fondo…

    Así que aquí está lo que he implementado:

    Como no-tan-simple-las solicitudes (véase punto 1) hacer una pre-vuelo de llamada, es necesario agregar el siguiente en el fichero de rutas:

    POST /url_to_json_webservice        controllers.myJsonWebServices.myJsonWebService
    OPTIONS /url_to_json_webservice     controllers.myJsonWebServices.checkPreFlight

    y, a continuación, configure el siguiente método en el controlador:

    public static Result checkPreFlight() {
        response().setHeader("Access-Control-Allow-Origin", "*");       //Need to add the correct domain in here!!
        response().setHeader("Access-Control-Allow-Methods", "POST");   //Only allow POST
        response().setHeader("Access-Control-Max-Age", "300");          //Cache response for 5 minutes
        response().setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");         //Ensure this header is also allowed!  
        return ok();
    }

    Cuenta que puede haber más encabezados de lo que se necesita aquí, así que por favor verifique que usted necesita!!

    También recuerde agregar lo siguiente al final de su controlador método que devuelve el resultado en JSon (como en mi pregunta anterior):

    public static Result myJsonWebService() {
      ...
      response().setHeader("Access-Control-Allow-Origin", "*");
      return ok(toJson(jsonObject));
    }

    OriginalEl autor mstreffo

  3. 3

    Una buena manera de hacer esto es mediante la extensión de las Acciones:

    package actions;
    
    import play.*;
    import play.mvc.*;
    import play.mvc.Http.Context;
    import play.mvc.Http.Response;
    
    public class CorsAction extends Action.Simple {
    
    public Result call(Context context) throws Throwable{
        Response response = context.response();
        response.setHeader("Access-Control-Allow-Origin", "*");
    
        //Handle preflight requests
        if(context.request().method().equals("OPTIONS")) {
            response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, PUT, DELETE");
            response.setHeader("Access-Control-Max-Age", "3600");
            response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, Authorization, X-Auth-Token");
            response.setHeader("Access-Control-Allow-Credentials", "true");
    
            return ok();
        }
    
        response.setHeader("Access-Control-Allow-Headers","X-Requested-With, Content-Type, X-Auth-Token");
        return delegate.call(context);
    }
    
    }

    A continuación, en sus controladores de añadir esta línea:

    @With(CorsAction.class)

    Entonces todo ok() solicitudes de responder con la por encima de los encabezados.

    OriginalEl autor Skeep

  4. 1

    Implementado como un Scala de Filtro (jugar 2.2.x):

    import scala.concurrent.ExecutionContext.Implicits.global
    import play.api.mvc._
    import play.api.mvc.Results._
    import play.api.http.HeaderNames._
    
    object Cors extends Filter {
      def apply(next: (RequestHeader) => Future[SimpleResult])(request: RequestHeader): Future[SimpleResult] = {
        val origin = request.headers.get(ORIGIN).getOrElse("*")
        if (request.method == "OPTIONS") {
          val response = Ok.withHeaders(
            ACCESS_CONTROL_ALLOW_ORIGIN -> origin,
            ACCESS_CONTROL_ALLOW_METHODS -> "POST, GET, OPTIONS, PUT, DELETE",
            ACCESS_CONTROL_MAX_AGE -> "3600",
            ACCESS_CONTROL_ALLOW_HEADERS -> s"$ORIGIN, X-Requested-With, $CONTENT_TYPE, $ACCEPT, $AUTHORIZATION, X-Auth-Token",
            ACCESS_CONTROL_ALLOW_CREDENTIALS -> "true"
          )
          Future.successful(response)
        } else {
          next(request).map {
            res => res.withHeaders(
              ACCESS_CONTROL_ALLOW_ORIGIN -> origin,
              ACCESS_CONTROL_ALLOW_CREDENTIALS -> "true"
            )
          }
        }
      }
    }
    
    object Global extends WithFilters(Cors) {...}

    OriginalEl autor Mads Lundeland

Dejar respuesta

Please enter your comment!
Please enter your name here