376 votos

¿Cómo puedo enviar una solicitud POST dominios vía JavaScript?

¿Cómo puedo enviar una solicitud POST dominios vía JavaScript?

Notas - no actualice la página, y tengo que tomar y analizar la respuesta luego.

Agradeceremos mucho su ayuda con algunos ejemplos de código.

280voto

rynop Puntos 7818

Actualización: Antes de continuar todo el mundo debería leer y comprender la html5rocks tutorial en CORS. Es fácil de entender y muy clara.

Si usted controla el servidor de ser Publicado, simplemente aprovechar el "Cross-Origin Resource Sharing estándar" mediante la configuración de encabezados de respuesta en el servidor. Esta respuesta es discutido en otras respuestas en este hilo, pero no muy claramente, en mi opinión.

En resumen aquí es cómo usted puede cumplir con la cruz de dominio POST de from.com/1.html a to.com/postHere.php (el uso de PHP como un ejemplo). Nota: sólo se necesita configurar Access-Control-Allow-Origin NO OPTIONS de solicitudes : en este ejemplo se establece siempre todos los encabezados de un pequeño fragmento de código.

  1. En postHere.php la instalación de los siguientes:

    switch ($_SERVER['HTTP_ORIGIN']) {
        case 'http://from.com': case 'https://from.com':
        header('Access-Control-Allow-Origin: '.$_SERVER['HTTP_ORIGIN']);
        header('Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS');
        header('Access-Control-Max-Age: 1000');
        header('Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With');
        break;
    }
    

    Esto permite que la secuencia de comandos para hacer cross domain POST, GET y OPCIONES. Esto se hará evidente a medida que continúe leyendo...

  2. La configuración de su dominio cruzado POSTERIOR de JS (jQuery ejemplo):

    $.ajax({
        type: 'POST',
        url: 'https://to.com/postHere.php',
        crossDomain: true,
        data: '{"some":"json"}',
        dataType: 'json',
        success: function(responseData, textStatus, jqXHR) {
            var value = responseData.someKey;
        },
        error: function (responseData, textStatus, errorThrown) {
            alert('POST failed.');
        }
    });
    

Al hacer el POST en el paso 2, el navegador envía una "OPCIONES" método para el servidor. Este es un "oler" por el navegador para ver si el servidor es fresco con usted Publicación. El servidor responde con un "Access-Control-Allow-Origin" diciendo al navegador de su OK para POST|GET|ORIGEN si la solicitud se originó a partir de "http://from.com" o "https://from.com". Ya que el servidor está de acuerdo, el navegador va a hacer una 2ª solicitud (esta vez un POST). Es una buena práctica para tener su cliente establecer el tipo de contenido que está enviando, de modo que necesitará para permitir que así.

MDN tiene un gran relato acerca de HTTP de control de acceso, que entra en detalles de cómo la totalidad de la obras de flujo. De acuerdo con sus documentos, se deberá "trabajar en los navegadores que soporte cross-site XMLHttpRequest". Esto es un poco engañoso, sin embargo, como yo CREO que sólo los navegadores modernos permiten cruz de dominio POST. Sólo he comprobado que esto funciona con safari,chrome,FF 3.6.

Tenga en cuenta lo siguiente si haces esto:

  1. Su servidor tendrá que manejar 2 peticiones por operación
  2. Usted tendrá que pensar acerca de las implicaciones de seguridad. Tenga cuidado antes de hacer algo como 'Access-Control-Allow-Origin: *'
  3. Esto no funciona en los navegadores móviles. En mi experiencia, que no permiten la cruz de dominio POST. He probado android, iPad, iPhone
  4. Hay un gran error en FF < 3.6 donde si el servidor devuelve un no 400 código de respuesta Y hay un cuerpo de respuesta (errores de validación por ejemplo), FF 3.6 no puedo conseguir el cuerpo de la respuesta. Este es un gran dolor en el culo, ya que no pueden utilizar un buen DESCANSO en las prácticas. Vea el error aquí (su presentadas en virtud de jQuery, pero mi conjetura es que es un FF error - parece estar fijo en FF4).
  5. Siempre devolver los encabezados de arriba, no sólo en la OPCIÓN de solicitudes. FF necesidades en la respuesta del POST.

89voto

Dan Fabulich Puntos 6143

Si usted controlar el servidor remoto, usted probablemente debería usar CORS, como se describe en la respuesta a esta pregunta; se apoya en IE8 y de seguridad, y todas las versiones recientes de FF, GC, y Safari.

Pero si usted no controlar el servidor remoto, o si hay que apoyar a IE7, usted probablemente quiera usar un iframe técnica.

  1. Crear un iframe con un nombre único. (iframes utilizar un espacio de nombres global para todo el navegador, así que escoja un nombre que ningún otro sitio web que se utilice.)
  2. Construir una forma oculta de insumos, la orientación de las iframe.
  3. Enviar el formulario.

Aquí el código de ejemplo; los he probado en IE6, IE7, IE8, IE9, FF4, GC11, S5.

function crossDomainPost() {
  // Add the iframe with a unique name
  var iframe = document.createElement("iframe");
  var uniqueString = "CHANGE_THIS_TO_SOME_UNIQUE_STRING";
  document.body.appendChild(iframe);
  iframe.style.display = "none";
  iframe.contentWindow.name = uniqueString;

  // construct a form with hidden inputs, targeting the iframe
  var form = document.createElement("form");
  form.target = uniqueString;
  form.action = "http://INSERT_YOUR_URL_HERE";
  form.method = "POST";

  // repeat for each parameter
  var input = document.createElement("input");
  input.type = "hidden";
  input.name = "INSERT_YOUR_PARAMETER_NAME_HERE";
  input.value = "INSERT_YOUR_PARAMETER_VALUE_HERE";
  form.appendChild(input);

  document.body.appendChild(form);
  form.submit();
}

¡Cuidado! Usted no será capaz de leer directamente la respuesta del POST, desde el iframe existe en un dominio independiente. Marcos no pueden comunicarse unos con otros de diferentes dominios; esta es la política de mismo origen.

Si el control remoto del servidor, pero no puede usar CORS, por alguna razón, hay maneras de trabajar alrededor de la política de mismo origen, por ejemplo, utilizando window.postMessage y/o una de una serie de bibliotecas que permite enviar cruz-dominio cruz-marco de mensajes en los navegadores antiguos:

Si no controlas el servidor remoto y, a continuación, usted no puede leer la respuesta del POST, período. Esto podría causar problemas de seguridad en caso contrario.

40voto

Lou Franco Puntos 48823
  1. Crear un iFrame,
  2. poner un formulario en él con entradas ocultas,
  3. establecer la acción del formulario a la URL
  4. Añadir iframe a documento
  5. Envíe el formulario

Pseudocódigo

 var ifr = document.createElement('iframe');
 var frm = document.createElement('form');
 frm.setAttribute("action", "yoururl");
 frm.setAttribute("method", "post");

 // create hidden inputs, add them
 // not shown, but similar (create, setAttribute, appendChild)

 ifr.appendChild(frm);
 document.body.appendChild(ifr);
 frm.submit();

Probablemente quieras el iframe, para ser escondida y posición absoluta del estilo. No estoy seguro podrán publicar sitio cruzado por el navegador, pero si es así, esto es cómo hacerlo.

14voto

Robb Lovell Puntos 139

Si tienes acceso a todos los servidores involucrados, poner lo siguiente en el encabezado de la respuesta de la página solicitada en el otro dominio:

PHP:

header('Access-Control-Allow-Origin: *');

Por ejemplo, en código de Drupal xmlrpc.php haría esto:

function xmlrpc_server_output($xml) {
    $xml = '<?xml version="1.0"?>'."\n". $xml;
    header('Connection: close');
    header('Content-Length: '. strlen($xml));
    header('Access-Control-Allow-Origin: *');
    header('Content-Type: application/x-www-form-urlencoded');
    header('Date: '. date('r'));
    // $xml = str_replace("\n", " ", $xml); 

    echo $xml;
    exit;
}

Probablemente esto crea un problema de seguridad, y debe asegurarse de que tomas las medidas necesarias para verificar la solicitud.

9voto

ndeuma Puntos 386

Compruebe el post_method función en http://taiyolab.com/mbtweet/scripts/twitterapi_call.js - un buen ejemplo para el iframe método descrito anteriormente.

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X