2011-11-16 12 views
34

tengo este código:XMLHttpRequest cambios de puestos de OPCIÓN

net.requestXHR = function() { 
    this.xhr = null; 
    if(window.XMLHttpRequest === undefined) { 
     window.XMLHttpRequest = function() { 
      try { 
       // Use the latest version of the activex object if available 
       this.xhr = new ActiveXObject("Msxml2.XMLHTTP.6.0"); 
      } 
      catch(e1) { 
       try { 
        // Otherwise fall back on an older version 
        this.xhr = new ActiveXObject("Mxsml2.XMLHTTP.3.0"); 
       } 
       catch(e2) { 
        //Otherwise, throw an error 
        this.xhr = new Error("Ajax not supported in your browser"); 
       } 
      } 
     }; 
    } 
    else 
     this.xhr = new XMLHttpRequest(); 
} 
net.requestXHR.prototype.post = function(url, data) { 
    if(this.xhr != null) { 
     this.xhr.open("POST", url); 
     this.xhr.setRequestHeader("Content-Type", "application/json"); 
     this.xhr.send(data); 
    } 
} 

    var rs = new net.requestSpeech(); 
    console.log(JSON.stringify(interaction)); 
    rs.post("http://localhost:8111", JSON.stringify(interaction)); 

cuando el envío ejecutar, tengo este registro:

OPTIONS http://localhost:8111/ [HTTP/1.1 405 Method Not Allowed 74ms] 

Y en localhost: 8111 tengo un serverResource reslet que aceptamos post , es problema de la misma política de origen? he modificado el restlet para poner el encabezado allow-origin y lo pruebo con otra solicitud GET http (en jquery) y trabajo bien. Tengo el problema de resolver el mismo origen porque uso un navegador html5 y mi servidor pone los encabezados en la respuesta, entonces, ¿por qué el envío me muestra este error? ¿Por qué cambiar POST por OPCIÓN? Gracias!

duplicado Posible ?: Creo que no, pero es verdad, el problema es la mismo para ambas preguntas, pero lo mío es se refiere ya que la pregunta que hay un problema con el navegador, y el otro, primero apunta a jquery. Por experiencia, el tiempo no cuenta como duplicado, las respuestas son diferentes, pero es verdad que ambas preguntas complementan entre sí.

+0

Posible duplicado de [¿Por qué recibo una solicitud de OPCIONES en lugar de una solicitud GET?] (Https://stackoverflow.com/questions/1256593/why-am-i-getting-an-options-request-instead-of-a -get-request) – Carvallegro

Respuesta

56

Sí, este es un "problema con la política del mismo origen". Está realizando su solicitud a un servidor diferente o a un puerto diferente, lo que significa que se trata de una solicitud HTTP entre sitios. Esto es lo que the documentation tiene que decir acerca de estas solicitudes:

Además, para los métodos de petición HTTP que pueden causar efectos secundarios en los datos del servidor (en particular, para los métodos HTTP que no sea GET, o para POST uso con ciertos tipos MIME), la especificación exige que los navegadores "comprueben previamente" la solicitud, soliciten los métodos compatibles de el método de solicitud HTTP OPTIONS y luego, al "aprobación" del servidor, envíen la solicitud real con el real Método de solicitud HTTP.

Hay una descripción más detallada en el CORS standard (sección "Solicitud de origen cruzado con verificación previa"). Su servidor debe permitir la solicitud OPTIONS y enviar una respuesta con los encabezados Access-Control-Allow-Origin, Access-Control-Allow-Headers y Access-Control-Allow-Methods que permitan la solicitud. A continuación, el navegador realizará la solicitud real POST.

+1

¿Qué puedo hacer en el caso cuando no puedo modificar el comportamiento del servidor? No puedo acceder a su código fuente – gbaor

+1

@gbaor: puede usar [JSONP] (http://en.wikipedia.org/wiki/JSONP) que no tiene restricciones de origen idéntico o (si el servidor no admite eso tampoco) puede ejecutar una secuencia de comandos del lado del servidor en su propio servidor que solicitará los datos del otro servidor y lo devolverá; a continuación, su código JavaScript puede obtener estos datos de su servidor que tiene el mismo origen. –

9

Estaba teniendo este problema exacto de un código JavaScript que envió un contenido ajax.

Con el fin de permitir que la Solicitud de origen cruzado con la comprobación preliminar que tenía que hacer esto en el .aspx que estaba recibiendo la petición:

//Check the petition Method 
if (Request.HttpMethod == "OPTIONS") 
{ 
    //In case of an OPTIONS, we allow the access to the origin of the petition 
    string vlsOrigin = Request.Headers["ORIGIN"]; 
    Response.AddHeader("Access-Control-Allow-Origin", vlsOrigin); 
    Response.AddHeader("Access-Control-Allow-Methods", "POST"); 
    Response.AddHeader("Access-Control-Allow-Headers", "accept, content-type"); 
    Response.AddHeader("Access-Control-Max-Age", "1728000"); 
} 

Hay que tener cuidado y comprobar lo cabeceras están siendo preguntado por su petición. Los revisé usando Fiddler.

Espero que esto sirva a alguien en el futuro.

1

Como han señalado otros, esto es algo de CORS.

Esto es cómo manejar la situación en Nginx (basado en this source):

location/{ 
    if ($request_method = OPTIONS) { 
     add_header Access-Control-Allow-Origin "http://example.com"; 
     add_header Access-Control-Allow-Methods "GET, OPTIONS"; 
     add_header Access-Control-Allow-Headers "Authorization"; 
     add_header Access-Control-Allow-Credentials "true"; 
     add_header Content-Length 0; 
     add_header Content-Type text/plain; 
     return 200; 
    } 
} 

Si desea permitir CORS solicitudes de cualquier origen, sustituyen,

add_header Access-Control-Allow-Origin "http://example.com"; 

con

add_header Access-Control-Allow-Origin "*"; 

Si no utiliza la autorización, no necesitará este bit:

add_header Access-Control-Allow-Headers "Authorization"; 
add_header Access-Control-Allow-Credentials "true"; 

Para la API estoy desarrollando Necesitaba a la lista blanca 3: métodos de petición GET, POST y opciones, y una cabecera X-App-Id, por lo que esto nos lo terminé haciendo:

if ($request_method = OPTIONS) { 
    add_header Access-Control-Allow-Origin "*"; 
    add_header Access-Control-Allow-Methods "GET, POST, OPTIONS"; 
    add_header Access-Control-Allow-Headers "X-App-Id"; 
    add_header Content-Length 0; 
    add_header Content-Type text/plain; 
    return 200; 
} 
Cuestiones relacionadas