¿Cómo envío una solicitud POST entre dominios a través de JavaScript?
Notas: no debería actualizar la página, y luego necesito obtener y analizar la respuesta.
javascript
ajax
cross-domain
Ido Schacham
fuente
fuente
Respuestas:
Actualización: antes de continuar, todos deberían leer y comprender el tutorial html5rocks en CORS. Es fácil de entender y muy claro.
Si controla el servidor que se está PUBLICANDO, simplemente aproveche el "Estándar de intercambio de recursos de origen cruzado" configurando encabezados de respuesta en el servidor. Esta respuesta se discute en otras respuestas en este hilo, pero no muy claramente en mi opinión.
En resumen, así es como se realiza la POST entre dominios desde from.com/1.html a to.com/postHere.php (usando PHP como ejemplo). Nota: solo necesita configurar las solicitudes
Access-Control-Allow-Origin
NOOPTIONS
- este ejemplo siempre establece todos los encabezados para un fragmento de código más pequeño.En postHere.php configura lo siguiente:
Esto permite que su script realice POST, GET y OPCIONES entre dominios. Esto quedará claro a medida que continúe leyendo ...
Configure su POST de dominio cruzado desde JS (ejemplo de jQuery):
Cuando realiza la POST en el paso 2, su navegador enviará un método de "OPCIONES" al servidor. Este es un "olfateo" por parte del navegador para ver si el servidor es bueno con usted PUBLICANDO. El servidor responde con un "Acceso-Control-Permitir-Origen" diciéndole al navegador que está BIEN POSTAR | OBTENER | ORIGEN si la solicitud se originó en " http://from.com " o " https://from.com ". Dado que el servidor está bien con él, el navegador realizará una segunda solicitud (esta vez una POST). Es una buena práctica que su cliente establezca el tipo de contenido que está enviando, por lo que también deberá permitirlo.
MDN tiene una excelente reseña sobre el control de acceso HTTP , que detalla cómo funciona todo el flujo. Según sus documentos, debería "funcionar en navegadores que admitan XMLHttpRequest entre sitios". Esto es un poco engañoso, sin embargo, como ya PIENSO sólo los navegadores modernos permiten la POST dominios. Solo he verificado que esto funciona con safari, chrome, FF 3.6.
Tenga en cuenta lo siguiente si hace esto:
fuente
400 Bad Request
elOPTIONS
pedido. y enfirefox
la segunda solicitud dePOST
nunca se hace. :(Si controla el servidor remoto, probablemente debería usar CORS, como se describe en esta respuesta ; es compatible con IE8 y versiones posteriores, y todas las versiones recientes de FF, GC y Safari. (Pero en IE8 y 9, CORS no le permitirá enviar cookies en la solicitud).
Por lo tanto, si no controla el servidor remoto, o si tiene que admitir IE7, o si necesita cookies y debe admitir IE8 / 9, es probable que desee utilizar una técnica de iframe.
Aquí hay un código de muestra; Lo probé en IE6, IE7, IE8, IE9, FF4, GC11, S5.
¡Tener cuidado! No podrá leer directamente la respuesta de la POST, ya que el iframe existe en un dominio separado. Los marcos no pueden comunicarse entre sí desde diferentes dominios; Esta es la política del mismo origen .
Si controla el servidor remoto pero no puede usar CORS (por ejemplo, porque está en IE8 / IE9 y necesita usar cookies), hay formas de evitar la política del mismo origen, por ejemplo, usando
window.postMessage
y / o una de una serie de bibliotecas que le permite enviar mensajes de marcos cruzados de dominios cruzados en navegadores antiguos:Si no controla el servidor remoto, entonces no puede leer la respuesta de la POST, punto. De lo contrario, causaría problemas de seguridad.
fuente
Pseudocódigo
Probablemente desee diseñar el iframe, para que esté oculto y en una posición absoluta. No estoy seguro de que el navegador permita la publicación en sitios cruzados, pero si es así, así es como se hace.
fuente
Mantenlo simple:
POST entre dominios:
uso
crossDomain: true,
no debe actualizar la página:
No, no se actualizará la página que el
success
oerror
asincrónica de devolución de llamada se llamará cuando el servidor de envío de la respuesta.Script de ejemplo:
fuente
crossDomain: true
Curiosamente no tiene absolutamente nada que ver con las solicitudes reales entre dominios. Si la solicitud es de dominio cruzado, jquery establece esto en verdadero de forma automática.Si tiene acceso a todos los servidores involucrados, coloque lo siguiente en el encabezado de la respuesta para la página que se solicita en el otro dominio:
PHP:
Por ejemplo, en el código xmlrpc.php de Drupal harías esto:
Esto probablemente crea un problema de seguridad, y debe asegurarse de tomar las medidas adecuadas para verificar la solicitud.
fuente
Verifique la
post_method
función en http://taiyolab.com/mbtweet/scripts/twitterapi_call.js , un buen ejemplo del método de iframe descrito anteriormente.fuente
Cree dos iframes ocultos (agregue "display: none;" al estilo css). Haga que su segundo iframe apunte a algo en su propio dominio.
Cree un formulario oculto, establezca su método para "publicar" con target = su primer iframe y, opcionalmente, establezca enctype en "multipart / form-data" (creo que quiere hacer POST porque desea enviar datos multiparte como imágenes ?)
Cuando esté listo, haga que el formulario envíe () la POST.
Si puede hacer que el otro dominio devuelva javascript que hará la comunicación entre dominios con marcos flotantes ( http://softwareas.com/cross-domain-communication-with-iframes ), entonces está de enhorabuena y puede capturar la respuesta también.
Por supuesto, si desea utilizar su servidor como proxy, puede evitar todo esto. Simplemente envíe el formulario a su propio servidor, que enviará la solicitud al otro servidor (suponiendo que el otro servidor no esté configurado para notar discrepancias de IP), obtenga la respuesta y devuelva lo que desee.
fuente
¡Una cosa más importante a tener en cuenta! En el ejemplo anterior se describe cómo usar
JQuery 1.6 y versiones anteriores tienen un error con XHR entre dominios. Según Firebug, no se enviaron solicitudes, excepto OPCIONES. Sin POST. En absoluto.
Pasé 5 horas probando / afinando mi código. Agregar muchos encabezados en el servidor remoto (script). Sin ningún efecto Pero más tarde, actualicé JQuery lib a 1.6.4, y todo funciona de maravilla.
fuente
Si desea hacer esto en un entorno ASP.net MVC con JQuery AJAX, siga estos pasos: (este es un resumen de la solución ofrecida en este hilo)
Suponga que "caller.com" (puede ser cualquier sitio web) necesita publicar en "server.com" (una aplicación ASP.net MVC)
En la aplicación "server.com" Web.config agregue la siguiente sección:
En "server.com", tendremos la siguiente acción en el controlador (llamado "Inicio") en el que publicaremos:
Luego, desde "caller.com", publique datos de un formulario (con la identificación html "formId") en "server.com" de la siguiente manera:
fuente
Hay una forma más (usando la función html5). Puede usar un iframe proxy alojado en ese otro dominio, enviar un mensaje usando postMessage a ese iframe, luego ese iframe puede hacer una solicitud POST (en el mismo dominio) y postMessage de vuelta con reposicionar a la ventana principal.
padre en sender.com
iframe en reciver.com
fuente
Nivel alto ... Debe tener una configuración de cname en su servidor para que other-serve.your-server.com apunte a other-server.com.
Su página crea dinámicamente un iframe invisible, que actúa como su transporte a other-server.com. Luego debe comunicarse a través de JS desde su página a other-server.com y recibir devoluciones de llamada que devuelvan los datos a su página.
Posible pero requiere coordinación de your-server.com y other-server.com
fuente
Creo que la mejor manera es usar XMLHttpRequest (por ejemplo, $ .ajax (), $ .post () en jQuery) con uno de los polyfills de intercambio de recursos de origen cruzado https://github.com/Modernizr/Modernizr/wiki/HTML5- Cross-Browser-Polyfills # wiki-CORS
fuente
Esta es una vieja pregunta, pero alguna tecnología nueva podría ayudar a alguien.
Si tiene acceso administrativo al otro servidor, puede usar el proyecto Forge de código abierto para realizar su POST entre dominios. Forge proporciona un contenedor XmlHttpRequest de dominio cruzado que aprovecha la API de socket sin procesar de Flash. La POST puede incluso hacerse sobre TLS.
La razón por la que necesita acceso administrativo al servidor al que está PUBLICANDO es porque debe proporcionar una política entre dominios que permita el acceso desde su dominio.
http://github.com/digitalbazaar/forge
fuente
Sé que esta es una vieja pregunta, pero quería compartir mi enfoque. Yo uso cURL como proxy, muy fácil y consistente. Cree una página php llamada submit.php y agregue el siguiente código:
Luego, en tu js (jQuery aquí):
fuente
Debería ser posible con una tabla personalizada YQL + JS XHR, eche un vistazo a: http://developer.yahoo.com/yql/guide/index.html
Lo uso para hacer algunos raspados html del lado del cliente (js), funciona bien (tengo un reproductor de audio completo, con búsqueda en internet / listas de reproducción / letras / última información de fm, todos los clientes js + YQL)
fuente
CORS es para ti. CORS es "Cross Origin Resource Sharing", es una forma de enviar una solicitud de dominio cruzado. Ahora XMLHttpRequest2 y Fetch API son compatibles con CORS, y puede enviar solicitudes POST y GET
Pero tiene sus límites. El servidor debe reclamar específicamente Access-Control-Allow-Origin , y no se puede establecer en '*'.
Y si desea que cualquier origen pueda enviarle una solicitud, necesita JSONP (también necesita establecer Access-Control-Allow-Origin , pero puede ser '*')
Para muchas solicitudes, si no sabe cómo elegir, creo que necesita un componente funcional completo para hacerlo. Permítame presentarle un componente simple https://github.com/Joker-Jelly/catta
Si está utilizando un navegador moderno (> IE9, Chrome, FF, Edge, etc.), le recomiendo que use un componente simple pero atractivo https://github.com/Joker-Jelly/catta . No tiene dependencia, Menos de 3 KB, y es compatible con Fetch, AJAX y JSONP con la misma sintaxis y opciones de muestra letales.
También admite todo el camino para importar a su proyecto, como el módulo ES6, CommonJS e incluso
<script>
en HTML.fuente
Si tiene acceso al servidor de dominio cruzado y no desea realizar ningún cambio de código en el lado del servidor, puede usar una biblioteca llamada - 'xdomain'.
Cómo funciona:
Paso 1: servidor 1: incluya la biblioteca xdomain y configure el dominio cruzado como esclavo:
Paso 2: en el servidor de dominio cruzado, cree un archivo proxy.html e incluya el servidor 1 como maestro:
Paso 3:
Ahora, puede hacer una llamada AJAX al proxy.html como punto final desde el servidor1. Esto es omitir la solicitud CORS. La biblioteca utiliza internamente una solución de iframe que funciona con credenciales y todos los métodos posibles: GET, POST, etc.
Consulta el código ajax:
fuente