Question jQuery AJAX domaine croisé


Voici deux pages, test.php et testserver.php.

test.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);
?>

Maintenant, mon problème: lorsque ces deux fichiers sont sur le même serveur (localhost ou serveur web), cela fonctionne et alert("Success") est appelé; Si c'est sur des serveurs différents, ce qui signifie testserver.php sur le serveur web et test.php sur localhost, cela ne fonctionne pas, et alert("Error") est en cours d'exécution. Même si l'URL dans ajax est modifiée en http://domain.com/path/to/file/testserver.php


440
2017-08-17 19:31


origine


Réponses:


Utilisation 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).");";
?>

L'écho pourrait être faux, ça fait un moment que j'ai utilisé php. Dans tous les cas, vous devez sortir callbackName('jsonString') remarquez les citations. jQuery transmettra son propre nom de rappel, vous devez donc le récupérer avec les paramètres GET.

Et comme Stefan Kendall l'a signalé, $ .getJSON () est une méthode abrégée, mais vous devez ajouter 'callback=?' à l'URL en tant que paramètre GET (oui, la valeur est ?, jQuery remplace cela par sa propre méthode de rappel générée).


393
2017-08-17 19:43



JSONP est une bonne option, mais il existe un moyen plus simple. Vous pouvez simplement définir le Access-Control-Allow-Origin en-tête sur votre serveur. Le régler à * acceptera les requêtes AJAX interdomaines de n'importe quel domaine. (https://developer.mozilla.org/fr/http_access_control)

La méthode pour y parvenir variera d'une langue à l'autre, bien sûr. Ici c'est dans Rails:

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

Dans cet exemple, le say_hello action acceptera les requêtes AJAX de n'importe quel domaine et retournera une réponse de "bonjour!".

Voici un exemple des en-têtes qu'il pourrait renvoyer:

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

Facile comme il est, il a des limitations de navigateur. Voir http://caniuse.com/#feat=cors.


195
2018-03-01 20:51



Vous pouvez contrôler cela via l'en-tête HTTP en ajoutant Contrôle d'accès-Autoriser-l'origine. Le paramétrer sur * acceptera les requêtes AJAX interdomaine de n'importe quel domaine.

En utilisant PHP c'est très simple, ajoutez simplement la ligne suivante dans le script auquel vous voulez avoir accès en dehors de votre domaine:

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

N'oubliez pas d'activer le module mod_headers dans httpd.conf.


27
2017-11-29 10:43



Vous devez regarder Politique d'origine identique:

En informatique, la même politique d'origine   est un concept de sécurité important pour un   nombre de programmation côté navigateur   langages, tels que JavaScript. le   la politique autorise les scripts s'exécutant sur   pages provenant du même site   pour accéder aux méthodes et   propriétés sans spécificité   restrictions, mais empêche l'accès à   la plupart des méthodes et propriétés à travers   pages sur différents sites.

Pour que vous puissiez obtenir des données, il faut que ce soit:

Même protocole et hôte

Vous devez mettre en œuvre JSONP pour y remédier.


19
2017-08-17 19:34



J'ai dû charger une page Web à partir du disque local "file: /// C: /test/htmlpage.html", appeler l'URL "http: //localhost/getxml.php", et le faire dans les navigateurs IE8 + et Firefox12 +, utiliser jQuery v1 .7.2 lib pour minimiser le code standard. Après avoir lu des dizaines d'articles ont finalement compris. Voici mon résumé.

  • Le script serveur (.php, .jsp, ...) doit renvoyer l'en-tête de réponse http Access-Control-Allow-Origin: *
  • avant d'utiliser jQuery ajax, définissez cet indicateur en javascript: jQuery.support.cors = true;
  • vous pouvez définir un drapeau une fois ou chaque fois avant d'utiliser la fonction jQuery ajax
  • maintenant je peux lire le document .xml dans IE et Firefox. Autres navigateurs que je n'ai pas testés.
  • le document de réponse peut être clair / texte, xml, json ou toute autre chose

Voici un exemple d'appel ajax jQuery avec quelques sysouts de débogage.

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
2018-05-16 12:34



Il est vrai que la stratégie de même origine empêche JavaScript de faire des requêtes sur plusieurs domaines, mais la spécification CORS autorise uniquement le type d'accès à l'API que vous recherchez et est prise en charge par le lot actuel des principaux navigateurs.

Découvrez comment activer le partage de ressources d'origine croisée pour le client et le serveur:

http://enable-cors.org/

"Le partage de ressources inter-origine (CORS) est une spécification qui permet un accès véritablement ouvert à travers les limites de domaine. Si vous diffusez du contenu public, envisagez d'utiliser CORS pour l'ouvrir à un accès JavaScript / navigateur universel."


10
2017-08-29 11:09



C'est possible, mais vous devez utiliser JSONP, pas JSON. Le lien de Stefan vous a indiqué la bonne direction. le page jQuery AJAX a plus d'informations sur JSONP.

Remy Sharp a un exemple détaillé en utilisant PHP.


9
2017-08-17 19:44



J'utilise le serveur Apache, j'ai donc utilisé le module mod_proxy. Activer les modules:

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

Puis ajouter:

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

Enfin, passez l'URL du proxy à votre script.


9
2018-04-02 11:58



La sécurité du navigateur empêche d'effectuer un appel ajax à partir d'une page hébergée sur un domaine vers une page hébergée sur un domaine différent; cela s'appelle le "politique de même origine".


8
2017-08-17 19:34



Il existe quelques exemples d'utilisation de JSONP, notamment la gestion des erreurs.

Toutefois, veuillez noter que l'événement d'erreur n'est pas déclenché lors de l'utilisation de JSONP! Voir: http://api.jquery.com/jQuery.ajax/ ou jQuery demande ajax en utilisant l'erreur jsonp


5
2018-05-10 14:56