jQuery AJAX cross domain


Aquí hay dos páginas, prueba.php y testserver.php.

Prueba.php

<script src="scripts/jq.js" type="text/javascript"></script>
<script>
    $(function() {
        $.ajax({url:"testserver.php",
            success:function() {
                alert("Success");
            },
            error:function() {
                alert("Error");
            },
            dataType:"json",
            type:"get"
        }
    )})
</script>

Testserver.php

<?php
$arr = array("element1",
             "element2",
             array("element31","element32"));
$arr['name'] = "response";
echo json_encode($arr);
?>

Ahora mi problema: cuando ambos archivos están en el mismo servidor (ya sea localhost o web server), funciona y se llama alert("Success"); Si está en servidores diferentes, significa testserver.php en servidor web y prueba.php en localhost, no funciona, y alert("Error") se está ejecutando. Incluso si la URL dentro de ajax se cambia a http://domain.com/path/to/file/testserver.php

Author: fibono, 2010-08-17

14 answers

Use JSONP.

JQuery:

$.ajax({
     url:"testserver.php",
     dataType: 'jsonp', // Notice! JSONP <-- P (lowercase)
     success:function(json){
         // do stuff with json (in this case an array)
         alert("Success");
     },
     error:function(){
         alert("Error");
     }      
});

PHP:

<?php
$arr = array("element1","element2",array("element31","element32"));
$arr['name'] = "response";
echo $_GET['callback']."(".json_encode($arr).");";
?>

El eco puede estar mal, hace tiempo que no uso php. En cualquier caso, debe mostrar callbackName('jsonString') las comillas. jQuery pasará su propio nombre de devolución de llamada, por lo que debe obtenerlo de los parámetros GET.

Y como Stefan Kendall publicó, $.getJSON () es un método abreviado, pero luego necesita agregar 'callback=?' a la url como parámetro GET (sí, el valor es ?, jQuery reemplaza esto con su propio método de devolución de llamada generado).

 395
Author: BGerrissen,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-11-07 01:26:47

JSONP es una buena opción, pero hay una manera más fácil. Simplemente puede configurar el encabezado Access-Control-Allow-Origin en su servidor. Configurarlo a * aceptará solicitudes AJAX entre dominios desde cualquier dominio. ( https://developer.mozilla.org/en/http_access_control)

El método para hacer esto variará de un idioma a otro, por supuesto. Aquí está en Rails:

class HelloController < ApplicationController
  def say_hello
    headers['Access-Control-Allow-Origin'] = "*"
    render text: "hello!"
  end
end

En este ejemplo, la acción say_hello aceptará solicitudes AJAX de cualquier dominio y devolverá una respuesta de " hello!".

Aquí es un ejemplo de las cabeceras que podría devolver:

HTTP/1.1 200 OK 
Access-Control-Allow-Origin: *
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Content-Type: text/html; charset=utf-8
X-Ua-Compatible: IE=Edge
Etag: "c4ca4238a0b923820dcc509a6f75849b"
X-Runtime: 0.913606
Content-Length: 6
Server: WEBrick/1.3.1 (Ruby/1.9.2/2011-07-09)
Date: Thu, 01 Mar 2012 20:44:28 GMT
Connection: Keep-Alive

Fácil como es, tiene algunas limitaciones del navegador. Véase http://caniuse.com/#feat=cors .

 195
Author: joshuarh,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-06-14 16:27:25

Puede controlar esto a través del encabezado HTTP agregando Access-Control-Allow-Origin. Configurarlo en * aceptará solicitudes AJAX entre dominios desde cualquier dominio.

Usando PHP es realmente simple, simplemente agregue la siguiente línea en el script al que desea tener acceso fuera de su dominio:

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

No olvide habilitar el módulo mod_headers en httpd.conf.

 28
Author: Adorjan Princz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-10-14 15:04:03

Debe echar un vistazo a La misma política de origen :

En informática, la misma política de origen es un concepto de seguridad importante para número de programación del lado del navegador idiomas, como JavaScript. El la directiva permite que los scripts se ejecuten en páginas que se originan en el mismo sitio para acceder a los métodos de los demás y propiedades sin restricciones, pero impide el acceso a la mayoría de los métodos y propiedades páginas sobre diferentes sites.

Para que pueda obtener datos, tiene que ser:

Mismo protocolo y host

Debe implementar JSONP para solucionarlo.

 19
Author: Sarfraz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-09-23 21:09:21

Tuve que cargar la página web desde el disco local "file:///C:/test/htmlpage.html", llamada "http://localhost/getxml.php " url, y haga esto en los navegadores IE8 + y Firefox12+, use jQuery v1.7. 2 lib para minimizar el código repetitivo. Después de leer docenas de artículos finalmente lo descubrió. Aquí está mi resumen.

  • script de servidor (.php, .jsp, ...) debe devolver el encabezado de respuesta http Access-Control-Allow-Origin: *
  • antes de usar jQuery ajax, establezca esta bandera en javascript: jQuery.apoyo.cors = true;
  • puede configurar flag una vez o cada vez antes de usar la función ajax de jQuery
  • ahora puedo leer .documento xml en IE y Firefox. Otros navegadores que no he probado.
  • el documento de respuesta puede ser plain / text, xml, json o cualquier otra cosa

Aquí hay un ejemplo de llamada jQuery ajax con algunos sistemas de depuración.

jQuery.support.cors = true;
$.ajax({
    url: "http://localhost/getxml.php",
    data: { "id":"doc1", "rows":"100" },
    type: "GET",
    timeout: 30000,
    dataType: "text", // "xml", "json"
    success: function(data) {
        // show text reply as-is (debug)
        alert(data);

        // show xml field values (debug)
        //alert( $(data).find("title").text() );

        // loop JSON array (debug)
        //var str="";
        //$.each(data.items, function(i,item) {
        //  str += item.title + "\n";
        //});
        //alert(str);
    },
    error: function(jqXHR, textStatus, ex) {
        alert(textStatus + "," + ex + "," + jqXHR.responseText);
    }
});
 16
Author: Whome,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-05-16 12:34:37

Es cierto que la política del mismo origen impide que JavaScript realice solicitudes a través de dominios, pero la especificación CORS permite el tipo de acceso a la API que está buscando, y es compatible con el lote actual de los principales navegadores.

Vea cómo habilitar el intercambio de recursos de origen cruzado para cliente y servidor:

Http://enable-cors.org/

"Cross-Origin Resource Sharing (CORS) es una especificación que permite un acceso verdaderamente abierto a través de los límites de dominio. Si usted sirve contenido público, por favor considere usar CORS para abrirlo para el acceso universal de JavaScript/navegador."

 10
Author: Jason,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-08-29 11:09:47

Esto es posible, pero necesita usar JSONP, no JSON. El enlace de Stefan te apuntó en la dirección correcta. La página jQuery AJAX tiene más información sobre JSONP.

Remy Sharp tiene un ejemplo detallado usando PHP.

 9
Author: Paul Schreiber,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-08-17 19:44:07

Uso el servidor Apache, por lo que he usado el módulo mod_proxy. Habilitar módulos:

LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so

Luego añadir:

ProxyPass /your-proxy-url/ http://service-url:serviceport/

Finalmente, pase proxy-url a su script.

 9
Author: zenio,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-04-02 11:58:07

La seguridad del navegador impide realizar una llamada ajax desde una página alojada en un dominio a una página alojada en un dominio diferente; esto se denomina " política del mismo origen".

 8
Author: Jacob Mattison,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-08-17 20:43:07

Hay pocos ejemplos para usar JSONP que incluyan el manejo de errores.

Sin embargo, tenga en cuenta que el evento de error no se activa cuando se utiliza JSONP! Véase: http://api.jquery.com/jQuery.ajax / or jQuery ajax request using jsonp error

 5
Author: BillyTom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:10:46

Desde los documentos de Jquery (enlace):

  • Debido a las restricciones de seguridad del navegador, la mayoría de las solicitudes "Ajax" están sujetas a la misma política de origen; la solicitud no puede recuperar datos de un dominio, subdominio o protocolo diferente.

  • Las solicitudes de script y JSONP no están sujetas a las mismas restricciones de la directiva de origen.

Así que consideraría que necesita usar jsonp para la solicitud. Pero yo no he intentado esto.

 4
Author: William Clemens,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2010-08-17 19:43:33

Conozco 3 formas de resolver tu problema:

  1. Primero, si tiene acceso a ambos dominios, puede permitir el acceso a todos los demás dominios utilizando :

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

    O simplemente un dominio mediante la adición de código a continuación .archivo htaccess:

    <FilesMatch "\.(ttf|otf|eot|woff)$"> <IfModule mod_headers.c> SetEnvIf Origin "http(s)?://(www\.)?(google.com|staging.google.com|development.google.com|otherdomain.net|dev02.otherdomain.net)$" AccessControlAllowOrigin=$0 Header add Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin </IfModule> </FilesMatch>

  2. Puede tener una solicitud ajax a un archivo php en su servidor y manejar la solicitud a otro dominio usando este archivo php.

  3. puede usar jsonp , porque no necesita permiso. para ello puede leer nuestro amigo @BGerrissen respuesta.
 1
Author: Ali_Hr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-03-03 12:25:43

Para Microsoft Azure, es ligeramente diferente.

Azure tiene una configuración especial de CORS que debe establecerse. Es esencialmente lo mismo detrás de las escenas, pero simplemente establecer el encabezado joshuarh menciones no funcionará. La documentación de Azure para habilitar dominios cruzados se puede encontrar aquí:

Https://docs.microsoft.com/en-us/azure/app-service-api/app-service-api-cors-consume-javascript

Jugueteé con esto durante unas horas antes al darme cuenta de que mi plataforma de alojamiento tenía este entorno especial.

 0
Author: Josh Schultz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-07-24 15:02:53

Funciona, todo lo que necesitas:

PHP:

header('Access-Control-Allow-Origin: http://www.example.com');
header("Access-Control-Allow-Credentials: true");
header('Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS');

JS (jQuery ajax):

var getWBody = $.ajax({ cache: false,
        url: URL,
        dataType : 'json',
        type: 'GET',
        xhrFields: { withCredentials: true }
});
 0
Author: Paun Narcis Iulian,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2018-05-04 08:53:19