CORS - ¿Cómo se realiza una verificación previa de una httpprequest?

94

Estoy tratando de realizar una solicitud HTTP de dominio cruzado al servicio WCF (que soy de mi propiedad). He leído varias técnicas para trabajar con las limitaciones de secuencias de comandos de dominio cruzado. Debido a que mi servicio debe adaptarse tanto a las solicitudes GET como a las POST, no puedo implementar alguna etiqueta de script dinámica cuyo src sea la URL de una solicitud GET. Como soy libre de hacer cambios en el servidor, he comenzado a intentar implementar una solución alternativa que implica configurar las respuestas del servidor para incluir el encabezado "Access-Control-Allow-Origin" y las solicitudes de "verificación previa" con una solicitud de OPCIONES. Tuve la idea de esta publicación: Hacer que CORS funcione

En el lado del servidor, mi método web es agregar 'Access-Control-Allow-Origin: *' a la respuesta HTTP. Puedo ver que las respuestas incluyen este encabezado ahora. Mi pregunta es: ¿Cómo realizo una verificación previa de una solicitud (OPCIONES)? Estoy usando jQuery.getJSON para realizar la solicitud GET, pero el navegador cancela la solicitud de inmediato con el infame:

Origin http: // localhost no está permitido por Access-Control-Allow-Origin

¿Alguien está familiarizado con esta técnica CORS? ¿Qué cambios deben realizarse en el cliente para realizar una verificación previa de mi solicitud?

¡Gracias!

Mella
fuente

Respuestas:

158

Durante la solicitud de verificación previa, debería ver los dos encabezados siguientes: Access-Control-Request-Method y Access-Control-Request-Headers. Estos encabezados de solicitud solicitan permisos al servidor para realizar la solicitud real. Su respuesta previa al vuelo debe reconocer estos encabezados para que funcione la solicitud real.

Por ejemplo, supongamos que el navegador realiza una solicitud con los siguientes encabezados:

Origin: http://yourdomain.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: X-Custom-Header

Su servidor debería responder con los siguientes encabezados:

Access-Control-Allow-Origin: http://yourdomain.com
Access-Control-Allow-Methods: GET, POST
Access-Control-Allow-Headers: X-Custom-Header

Preste especial atención al encabezado de respuesta Access-Control-Allow-Headers. El valor de este encabezado debe ser el mismo encabezado en el encabezado de solicitud Access-Control-Request-Headers, y no puede ser '*'.

Una vez que envíe esta respuesta a la solicitud de verificación previa, el navegador realizará la solicitud real. Puede obtener más información sobre CORS aquí: http://www.html5rocks.com/en/tutorials/cors/

monsur
fuente
¿Podrías agregar varios dominios a Access-Control-Allow-Origin?
botbot
@botbot Probablemente ya hayas resuelto esto, pero en caso de que otros se pregunten, puedes hacerloAccess-Control-Allow-Origin: *
Steve Chambers
2
Posiblemente me perdí algo. Entonces, ¿debería enviar dos solicitudes XMLHttp? Uno para la verificación previa; verifique la respuesta en caso de éxito y luego envíe la consulta real?
Kangkan
14
@Kangkan, no necesita preocuparse por enviar la solicitud de verificación previa. Si la solicitud necesita una verificación previa, el navegador se la enviará.
monsur
4
GRACIAS por el bit de 'prestar especial atención' ... que resolvió mi problema con node / expressjs. Pude agregar un filtro para detectar estas solicitudes de //cors and preflight filtering app.all('*', function(req, res, next){.. //preflight needs to return exact request-header res.set('Access-Control-Allow-Headers', req.headers['access-control-request-headers']); if ('OPTIONS' == req.method) return res.send(204);next(); });
verificación previa
0

Aunque este hilo se remonta a 2014, el problema aún puede ser actual para muchos de nosotros. Así es como lo manejé en un contexto jQuery 1.12 / PHP 5.6:

  • jQuery envió su solicitud XHR utilizando solo encabezados limitados; solo se envió 'Origen'.
  • No fue necesaria ninguna solicitud de verificación previa.
  • El servidor solo tenía que detectar tal solicitud y agregar el "Access-Control-Allow-Origin:". $ _SERVER ['HTTP_ORIGIN'] encabezado, después de detectar que se trataba de un XHR de origen cruzado.

Ejemplo de código PHP:

if (!empty($_SERVER['HTTP_ORIGIN'])) {
    // Uh oh, this XHR comes from outer space...
    // Use this opportunity to filter out referers that shouldn't be allowed to see this request
    if (!preg_match('@\.partner\.domain\.net$@'))
        die("End of the road if you're not my business partner.");

    // otherwise oblige
    header("Access-Control-Allow-Origin: " . $_SERVER['HTTP_ORIGIN']);
}
else {
    // local request, no need to send a specific header for CORS
}

En particular, no agregue una exit;verificación previa ya que no es necesaria.

Fabien Haddadi
fuente