470 votes

jQuery AJAX cross domain

Voici deux pages, test.php et servertest.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>

testerver.php

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

Maintenant mon problème, quand ces deux fichiers sont sur le même serveur (soit localhost ou serveur web), cela fonctionne et alert("Success"), Si c'est sur des côtés différents, je veux dire, testserver.php dans le serveur web et test.php sur localhost, cela ne fonctionne pas, alert("Error") s'exécute. Même si l'url dans l'ajax a changé en http://domain.com/path/to/file/testserver.php

S'il vous plaît, n'importe quel expert, c'est très simple pour vous mais pas pour moi car je suis nouveau dans ce domaine.

411voto

BGerrissen Points 9274

Utilisez 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).");";  // 09/01/12 corrected the statement
?>

L'écho est peut-être faux, ça fait un moment que je n'ai pas fait de php. Dans tous les cas, vous devez sortir callbackName('jsonString') sans les guillemets. jQuery passera son propre nom de callback, vous devez donc le récupérer dans les paramètres GET.

Et comme Stefan Kendall a posté, $.getJSON() est une méthode raccourcie, mais vous devez alors ajouter 'callback=?' à l'url comme paramètre GET (oui, la valeur est ?, jQuery la remplace par sa propre méthode de rappel).

201voto

joshuabc Points 2131

JSONP est une bonne option, mais il existe un moyen plus simple. Vous pouvez simplement définir l'option Access-Control-Allow-Origin sur votre serveur. En lui donnant la valeur * acceptera les demandes AJAX inter-domaines provenant de n'importe quel domaine. ( https://developer.mozilla.org/en/http_access_control )

La méthode pour y parvenir varie bien sûr d'une langue à l'autre. Voici la méthode dans Rails :

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

Dans cet exemple, le say_hello acceptera les requêtes AJAX provenant de n'importe quel domaine et renverra une réponse de type "hello".

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

Aussi simple qu'il soit, il présente certaines limites en matière de navigation. Voir http://caniuse.com/#feat=cors .

20voto

Sarfraz Points 168484

Vous devez jeter un coup d'œil à Politique de l'origine identique :

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

Pour que vous puissiez obtenir des données, il faut qu'elles le soient :

Même protocole et même hôte

Vous devez mettre en œuvre JSONP pour le contourner.

17voto

Whome Points 2303

J'ai dû charger la page web depuis le disque local "file:///C:/test/htmlpage.html", appeler l'url "http://localhost/getxml.php", et faire cela dans les navigateurs IE8+ et Firefox12+, utiliser la librairie jQuery v1.7.2 pour minimiser le code passe-partout. Après avoir lu des dizaines d'articles, j'ai finalement trouvé la solution. Voici mon résumé.

  • Le serveur script (.php, .jsp, ...) doit renvoyer l'en-tête de réponse http Access-Control-Allow-Origin : *
  • avant d'utiliser jQuery ajax, définissez ce drapeau en javascript : jQuery.support.cors = true ;
  • Vous pouvez définir le drapeau une fois ou à chaque fois avant d'utiliser la fonction jQuery ajax.
  • Je peux maintenant lire les documents .xml dans IE et Firefox. Je n'ai pas testé les autres navigateurs.
  • le document de réponse peut être du texte brut, du xml, du json ou tout autre document.

Voici un exemple d'appel jQuery ajax avec quelques sorties 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);
    }
});

9voto

Paul Schreiber Points 7214

C'est possible, mais vous devez utiliser JSONP, et non JSON. Le lien de Stefan vous a orienté dans la bonne direction. Le site Page AJAX jQuery contient plus d'informations sur JSONP.

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X