javascript - resource - jquery get cross domain
jQuery AJAX cross domain (14)
Aquí hay dos páginas, test.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 estos dos archivos están en el mismo servidor (localhost o servidor web), funciona y se llama alert("Success")
; Si está en servidores diferentes, es decir, testserver.php en el servidor web y test.php en localhost, no funciona y se está ejecutando una alert("Error")
. Incluso si la URL dentro de ajax se cambia a http://domain.com/path/to/file/testserver.php
Conozco 3 formas de resolver su problema:
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 agregando el código de abajo al 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>
puede tener una solicitud ajax para un archivo php en su servidor y manejar la solicitud a otro dominio usando este archivo php.
- Puedes usar jsonp, porque no necesita permiso. Para esto puedes leer nuestra respuesta de amigo @BGerrissen.
De 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 secuencias de comandos y JSONP no están sujetas a las mismas restricciones de la política de origen.
Por lo tanto, consideraría que debe utilizar jsonp para la solicitud. Pero no he intentado esto yo mismo.
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 solo el tipo de acceso a API que está buscando, y es compatible con el lote actual de los principales navegadores.
Vea cómo habilitar el uso compartido de recursos de origen cruzado para el cliente y el servidor:
"El uso compartido de recursos de origen cruzado (CORS) es una especificación que permite un acceso verdaderamente abierto a través de los límites de los dominios. Si sirve contenido público, considere usar CORS para abrirlo para el acceso universal a JavaScript / navegador".
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 .
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 }
});
Hay algunos ejemplos para usar JSONP que incluyen el manejo de errores.
Sin embargo, tenga en cuenta que el evento de error no se activa cuando se utiliza JSONP. Consulte: http://api.jquery.com/jQuery.ajax/ o jQuery ajax request utilizando el error jsonp
JSONP es una buena opción, pero hay una manera más fácil. Simplemente puede establecer el encabezado de Access-Control-Allow-Origin
en su servidor. Al establecerlo en *
se aceptarán solicitudes AJAX de dominio cruzado de 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 "hola!".
Aquí hay un ejemplo de los encabezados 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. Ver http://caniuse.com/#feat=cors .
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 llama la " política del mismo origen ".
Necesitas echar un vistazo a la Política de Origen Mismo :
En informática, la misma política de origen es un concepto de seguridad importante para varios lenguajes de programación del lado del navegador, como JavaScript. La política permite que los scripts que se ejecutan en páginas que se originan en el mismo sitio tengan acceso a los métodos y propiedades de los demás sin restricciones específicas, pero previene el acceso a la mayoría de los métodos y propiedades en las páginas de diferentes sitios.
Para que puedas obtener datos, tiene que ser:
Mismo protocolo y host
Necesitas implementar JSONP para solucionarlo.
Puede controlar esto a través del encabezado HTTP agregando Access-Control-Allow-Origin . Al establecerlo en *, se aceptarán solicitudes AJAX de dominio cruzado de cualquier dominio.
Usar PHP es realmente simple, solo agregue la siguiente línea en el script al que desea tener acceso fuera de su dominio:
header("Access-Control-Allow-Origin: *");
No se olvide de habilitar el módulo mod_headers en httpd.conf.
Tuve que cargar la página web desde el disco local "file: /// C: /test/htmlpage.html", llamada "http: //localhost/getxml.php" url, y hacer esto en los navegadores IE8 + y Firefox12 +, usar jQuery v1 .7.2 lib para minimizar el código repetitivo. Después de leer docenas de artículos, finalmente lo resolvieron. Aquí está mi resumen.
- el script del servidor (.php, .jsp, ...) debe devolver el encabezado de respuesta http Access-Control-Allow-Origin: *
- antes de usar jQuery ajax establezca esta marca en javascript: jQuery.support.cors = true;
- puede configurar el indicador una vez o siempre antes de usar la función ajax jQuery
- Ahora puedo leer el documento .xml en IE y Firefox. Otros navegadores que no probé.
- El documento de respuesta puede ser simple / texto, xml, json o cualquier otra cosa.
Aquí hay un ejemplo de llamada jQuery ajax con algunos sysouts 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);
}
});
Utilice 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 equivocado, ha pasado un tiempo desde que usé php. En cualquier caso, debe mostrar las callbackName(''jsonString'')
. jQuery pasará su propio nombre de devolución de llamada, por lo que debe obtenerlo de los parámetros GET.
Y como publicó Stefan Kendall, $.getJSON() es un método abreviado, pero luego debe 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).
Yo uso el servidor Apache, por lo que he usado mod_proxy módulo. Habilitar módulos:
LoadModule proxy_module modules/mod_proxy.so
LoadModule proxy_http_module modules/mod_proxy_http.so
Luego añade:
ProxyPass /your-proxy-url/ http://service-url:serviceport/
Finalmente, pase el proxy-url a su script.
Para Microsoft Azure, es ligeramente diferente.
Azure tiene una configuración de CORS especial que debe establecerse. Esencialmente, es lo mismo detrás de escena, pero simplemente establecer el encabezado que menciona joshuarh 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
Jugué con esto por algunas horas antes de darme cuenta de que mi plataforma de alojamiento tenía esta configuración especial.