jQuery AJAX cross domain

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

.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: quand ces deux fichiers sont sur le même serveur (soit localhost soit web), il fonctionne et alert("Success") est appelé; S'il est sur des serveurs différents, ce qui signifie testserver.php sur le serveur web et test.php sur localhost, ça ne marche pas, et alert("Error") est en cours d'exécution. Même si l'URL à l'intérieur d'ajax est changée en http://domain.com/path/to/file/testserver.php

444
demandé sur fibono 2010-08-17 23:31:01

14 réponses

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

l'écho peut être erroné, ça fait longtemps que je n'ai pas utilisé php. Dans tous les cas, vous devez sortir callbackName('jsonString') noter les citations. jQuery va passer son propre nom de rappel, donc vous devez obtenir que de la param GET.

et comme Stefan Kendall posté, $.getJSON () est un méthode de raccourci, mais ensuite vous devez ajouter 'callback=?' à l'url comme paramètre GET (oui, la valeur est ?, jQuery remplace ceci par sa propre méthode de callback générée).

395
répondu BGerrissen 2017-11-07 01:26:47

JSONP est une bonne option, mais il y a un moyen plus facile. Vous pouvez simplement définir l'en-tête Access-Control-Allow-Origin sur votre serveur. Le paramétrer à * acceptera les requêtes AJAX multi-domaines de n'importe quel domaine. ( https://developer.mozilla.org/en/http_access_control )

La méthode pour ce faire varie d'une langue à l'autre, bien sûr. Ici, il est dans les Rails:

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

dans cet exemple, l'action say_hello accepter les requêtes AJAX de n'importe quel domaine et retourner une réponse de " hello!".

voici un exemple des en-têtes qu'il pourrait retourner:

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

s'il est Facile, il possède certaines des restrictions du navigateur. Voir http://caniuse.com/#feat=cors .

195
répondu joshuarh 2012-06-14 16:27:25

vous pouvez le contrôler via L'en-tête HTTP en ajoutant Access-Control-Allow-Origin . Le paramétrer à * acceptera les requêtes AJAX inter-domaines de n'importe quel domaine.

utilisant PHP c'est vraiment simple, il suffit d'ajouter la ligne suivante dans le script que 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.

28
répondu Adorjan Princz 2015-10-14 15:04:03

Vous devez avoir un coup d'oeil à Même Origine :

Dans le calcul, la même origine est un concept de sécurité important pour un nombre de programmes côté navigateur les langues, comme le JavaScript. Le la Politique permet aux scripts de fonctionner sur pages provenant du même site pour accéder aux autres méthodes et propriétés sans spécificité les restrictions, mais empêche l'accès à la plupart des méthodes et propriétés travers des 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 implémenter JSONP pour contourner cela.

19
répondu Sarfraz 2014-09-23 21:09:21

j'ai eu à charger la page web à partir du disque local "fichier:///C:/test/htmlpage.html", appel "http://localhost/getxml.PHP " url, et le faire dans IE8+ et Firefox12+ navigateurs, utilisez jQuery v1.7.2 lib pour minimiser le code boilerplate. Après avoir lu des dizaines d'articles enfin compris. Voici mon résumé.

  • serveur de script (.php,.JSP. ,..) doit retourner-tête de réponse http Access-Control-Allow-Origin: *
  • avant d'utiliser jQuery ajax drapeau en javascript: jQuery.soutien.la scro = true;
  • vous pouvez mettre le drapeau une fois ou chaque fois avant d'utiliser la fonction ajax de jQuery
  • maintenant je peux lire .document xml dans IE et Firefox. Autres navigateurs que je n'ai pas testés.
  • document de réponse peut être simple / texte, xml, json ou n'importe quoi d'autre

voici un exemple d'appel ajax de 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
répondu Whome 2012-05-16 12:34:37

il est vrai que la Politique de même origine empêche JavaScript de faire des requêtes à travers les domaines, mais la spécification CORS permet juste le type d'accès API que vous recherchez, et est pris en charge par le lot actuel des principaux navigateurs.

Voir comment activer le cross-origin resource sharing pour le client et le serveur:

http://enable-cors.org /

" Cross-Origin Resource Sharing (CORS) is a spécification qui permet un accès vraiment ouvert au-delà des limites du domaine. Si vous servez du contenu public, veuillez envisager d'utiliser CORS pour l'ouvrir à un accès JavaScript/navigateur universel."

10
répondu Jason 2013-08-29 11:09:47

C'est possible, mais vous devez utiliser JSONP, pas JSON. Stefan lien pointé dans la bonne direction. La page de jQuery AJAX contient plus d'informations sur JSONP.

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

9
répondu Paul Schreiber 2010-08-17 19:44:07

j'utilise le serveur Apache, donc j'ai 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 le proxy-url à votre script.

9
répondu zenio 2012-04-02 11:58:07

la sécurité du navigateur empêche de faire un appel ajax d'une page hébergée sur un domaine à une page hébergée sur un autre domaine; cela s'appelle la " Politique de même origine ".

8
répondu Jacob Mattison 2010-08-17 20:43:07

il y a peu d'exemples d'utilisation de JSONP qui incluent la gestion des erreurs.

cependant, veuillez noter que L'événement d'erreur n'est pas déclenché lorsque vous utilisez JSONP! Voir: http://api.jquery.com/jQuery.ajax/ ou jQuery ajax demande de l'aide jsonp erreur

5
répondu BillyTom 2017-05-23 12:10:46

De Jquery docs ( lien ):

  • en raison des restrictions de sécurité du navigateur, la plupart des requêtes" Ajax " sont soumises à la même politique d'origine; la requête ne peut pas récupérer avec succès des données à partir d'un domaine, d'un sous-domaine ou d'un protocole différent.

  • Les requêtes
  • Script et JSONP ne sont pas soumises aux mêmes restrictions de la Politique d'origine.

donc je suppose que vous devez utiliser jsonp pour la requête. Mais je n'ai pas essayé moi-même.

4
répondu William Clemens 2010-08-17 19:43:33

je sais 3 Façon de résoudre votre problème:

  1. tout d'abord, si vous avez accès aux deux domaines, vous pouvez autoriser l'accès à tous les autres domaines en utilisant:

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

    ou tout simplement un domaine en ajoutant du code ci-dessous .fichier 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="151910920" Header add Access-Control-Allow-Origin %{AccessControlAllowOrigin}e env=AccessControlAllowOrigin </IfModule> </FilesMatch>

  2. vous pouvez avoir une requête ajax vers un fichier php dans votre serveur et gérer la requête un autre domaine utilisant ce fichier php.

  3. vous pouvez utiliser jsonp , parce qu'il n'a pas besoin de permission. pour cela, vous pouvez lire notre ami @BGerrissen réponse.
1
répondu Ali_Hr 2018-03-03 12:25:43

pour Microsoft Azure, c'est légèrement différent.

Azur a un réglage de CORS spécial qui doit être réglé. C'est essentiellement la même chose dans les coulisses, mais le simple fait de placer l'en-tête que joshuarh mentionne ne marchera pas. La documentation Azure pour activer le domaine cross se trouve ici:

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

j'ai bricolé avec cela pendant quelques heures avant de réaliser que ma plate-forme d'hébergement avait ce cadre spécial.

0
répondu Josh Schultz 2017-07-24 15:02:53

cela fonctionne, tout ce dont vous avez besoin:

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
répondu Paun Narcis Iulian 2018-05-04 08:53:19