Comment puis-je envoyer une requête de courrier cross-domaine via JavaScript?

Comment puis-je envoyer une demande de courrier par domaine via JavaScript?

Notes-il ne devrait pas rafraîchir la page, et je dois saisir et analyser la réponse après.

votre aide avec quelques exemples de code sera très appréciée.

515
demandé sur informatik01 2008-11-18 16:43:53
la source

18 ответов

mise à jour: avant de continuer, tout le monde devrait lire et comprendre le tutoriel html5rocks sur CORS. Il est facile à comprendre et très clair.

si vous contrôlez le serveur affiché, il vous suffit de tirer parti de la" norme de partage des ressources Multi-origine " en positionnant les en-têtes de réponse sur le serveur. Cette réponse est discuté dans d'autres réponses dans ce fil, mais pas très clairement, à mon avis.

In voici comment vous accomplissez le poste de domaine croisé de from.com/1.html pour to.com/postHere.php (en utilisant PHP comme exemple). Note: vous n'avez qu'à définir Access-Control-Allow-Origin pour les requêtes NON OPTIONS - cet exemple définit toujours tous les en-têtes pour un petit morceau de code.

  1. Dans postHere.configuration de php est le suivant:

    switch ($_SERVER['HTTP_ORIGIN']) {
        case 'http://from.com': case 'https://from.com':
        header('Access-Control-Allow-Origin: '.$_SERVER['HTTP_ORIGIN']);
        header('Access-Control-Allow-Methods: GET, PUT, POST, DELETE, OPTIONS');
        header('Access-Control-Max-Age: 1000');
        header('Access-Control-Allow-Headers: Content-Type, Authorization, X-Requested-With');
        break;
    }
    

    cela permet à votre script de faire du cross domain POST, GET et OPTIONS. Cela deviendra clair comme vous continuer à lire...

  2. le programme d'Installation de votre croix de domaine POST JS (jQuery exemple):

    $.ajax({
        type: 'POST',
        url: 'https://to.com/postHere.php',
        crossDomain: true,
        data: '{"some":"json"}',
        dataType: 'json',
        success: function(responseData, textStatus, jqXHR) {
            var value = responseData.someKey;
        },
        error: function (responseData, textStatus, errorThrown) {
            alert('POST failed.');
        }
    });
    

lorsque vous faites le POST à l'étape 2, votre navigateur enverra une méthode "OPTIONS" au serveur. Il s'agit d'un" sniff " par le navigateur pour voir si le serveur est cool avec vous y poster. Le serveur répond avec un" Access-Control-Allow-Origin " indiquant au navigateur son OK pour poster|obtenir / ORIGIN si la demande originaire de " http://from.com " ou " https://from.com ". Puisque le serveur est OK avec lui, le navigateur va faire une 2ème requête (cette fois un POST). C'est une bonne pratique de demander à votre client de définir le type de contenu qu'il envoie - vous devrez donc autoriser cela aussi.

MDN a une grande écriture sur contrôle D'accès HTTP , qui va dans le détail de la façon dont le flux entier fonctionne. Selon leurs docs, il devrait "fonctionner dans les navigateurs qui prennent en charge cross-site XMLHttpRequest". Cela est un peu trompeur cependant, comme I penser seuls les navigateurs modernes permettent cross domain POST. J'ai seulement vérifié que cela fonctionne avec safari,chrome,FF 3.6.

gardez à l'esprit ce qui suit si vous faites cela:

  1. votre serveur devra traiter 2 requêtes par opération
  2. vous devrez penser à la sécurité implication. Soyez prudent avant de faire quelque chose comme 'Accès-Control-Allow-Origin: * '
  3. cela ne fonctionne pas sur les navigateurs mobiles. Dans mon expérience, ils ne permettent pas de croix domaine de POSTE. J'ai testé android, iPad, iPhone
  4. il y a un gros bug dans FF < 3.6 où si le serveur renvoie un code de réponse non 400 et qu'il y a un corps de réponse (erreurs de validation par exemple), FF 3.6 ne récupérera pas le corps de réponse. C'est une énorme douleur dans le cul, depuis vous ne pouvez pas utiliser de bonnes pratiques de repos. Voir le bogue ici (il a été déposé sous jQuery, mais à mon avis c'est un bogue FF - semble avoir été corrigé dans FF4).
  5. toujours retourner les en-têtes ci-dessus, pas seulement sur les demandes D'OPTION. FF en a besoin dans la réponse de la poste.
363
répondu rynop 2013-07-16 23:24:55
la source

si vous contrôlez le serveur distant, vous devriez probablement utiliser CORS, comme décrit dans cette réponse ; il est pris en charge dans IE8 et up, et toutes les versions récentes de FF, GC, et Safari. (Mais dans IE8 et 9, CORS ne vous permettra pas d'envoyer des cookies dans la demande.)

donc, si vous ne contrôlez pas le serveur distant, ou si vous devez prendre en charge IE7, ou si vous avez besoin de cookies et que vous devez prendre en charge IE8/9, vous voudrez probablement utiliser un technique iframe.

  1. créer une iframe avec un nom unique. (iframes utilisent un espace de nom global pour l'ensemble du navigateur, alors choisissez un nom qu'aucun autre site web n'utilisera.)
  2. construisent une forme avec des entrées cachées, ciblant l'iframe.
  3. Soumettre le formulaire.

voici un exemple de code; je l'ai testé sur IE6, IE7, IE8, IE9, FF4, GC11, S5.

function crossDomainPost() {
  // Add the iframe with a unique name
  var iframe = document.createElement("iframe");
  var uniqueString = "CHANGE_THIS_TO_SOME_UNIQUE_STRING";
  document.body.appendChild(iframe);
  iframe.style.display = "none";
  iframe.contentWindow.name = uniqueString;

  // construct a form with hidden inputs, targeting the iframe
  var form = document.createElement("form");
  form.target = uniqueString;
  form.action = "http://INSERT_YOUR_URL_HERE";
  form.method = "POST";

  // repeat for each parameter
  var input = document.createElement("input");
  input.type = "hidden";
  input.name = "INSERT_YOUR_PARAMETER_NAME_HERE";
  input.value = "INSERT_YOUR_PARAMETER_VALUE_HERE";
  form.appendChild(input);

  document.body.appendChild(form);
  form.submit();
}

attention! Vous ne pas être capable de lire directement la réponse de la POSTE, depuis l'iframe existe sur un domaine distinct. Les cadres ne sont pas autorisés à communiquer entre eux à partir de domaines différents; c'est la Politique de même origine .

si vous contrôlez le serveur distant mais que vous ne pouvez pas utiliser CORS (par exemple parce que vous êtes sur IE8/IE9 et que vous devez utiliser des cookies), il y a des façons de contourner la Politique de même origine, par exemple en utilisant window.postMessage et/ou l'une des nombreuses bibliothèques vous permettant d'envoyer des messages cross-domain cross-frame dans des navigateurs plus anciens:

si vous ne contrôlez pas le serveur distant, alors vous ne pouvez pas lire la réponse du POST, point. Il serait la cause de problèmes de sécurité autrement.

118
répondu Dan Fabulich 2017-05-23 15:03:03
la source
  1. créer une iFrame,
  2. y mettre une forme avec des entrées cachées,
  3. définit L'action du formulaire à L'URL,
  4. ajouter iframe au document
  5. soumettre le formulaire

Pseudo-code

 var ifr = document.createElement('iframe');
 var frm = document.createElement('form');
 frm.setAttribute("action", "yoururl");
 frm.setAttribute("method", "post");

 // create hidden inputs, add them
 // not shown, but similar (create, setAttribute, appendChild)

 ifr.appendChild(frm);
 document.body.appendChild(ifr);
 frm.submit();

vous voulez probablement style l'iframe, pour être caché et absolument positionné. Pas sûr que l'affichage cross site sera autorisé par le navigateur, mais si c'est le cas, voici comment le faire.

47
répondu Lou Franco 2008-11-18 16:49:36
la source

Keep it simple:

  1. poste interdomaines:

    utiliser crossDomain: true,

  2. ne devrait pas rafraîchir la page:

    Non, il ne va pas rafraîchir la page car le success ou error async callback sera appelé lorsque le serveur renvoie réponse.


exemple de script:

$.ajax({
        type: "POST",
        url: "http://www.yoururl.com/",
        crossDomain: true,
        data: 'param1=value1&param2=value2',
        success: function (data) {
            // do something with server response data
        },
        error: function (err) {
            // handle your error logic here
        }
    });
19
répondu Alain Gauthier 2017-07-25 15:30:51
la source

Si vous avez accès à tous les serveurs impliqués, placez le code suivant dans l'en-tête de la réponse pour la page demandée dans l'autre domaine:

PHP:

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

par exemple, dans xmlrpc de Drupal.code php vous feriez ceci:

function xmlrpc_server_output($xml) {
    $xml = '<?xml version="1.0"?>'."\n". $xml;
    header('Connection: close');
    header('Content-Length: '. strlen($xml));
    header('Access-Control-Allow-Origin: *');
    header('Content-Type: application/x-www-form-urlencoded');
    header('Date: '. date('r'));
    // $xml = str_replace("\n", " ", $xml); 

    echo $xml;
    exit;
}

cela crée probablement un problème de sécurité, et vous devez vous assurer de prendre les mesures appropriées pour vérifier la demande.

16
répondu Robb Lovell 2011-04-12 20:35:08
la source

vérifier la fonction post_method dans http://taiyolab.com/mbtweet/scripts/twitterapi_call.js - un bon exemple pour la méthode iframe décrite ci-dessus.

9
répondu ndeuma 2010-02-25 01:03:35
la source
  1. créer deux iframes cachées (ajouter" display: none; " au style css). Faites votre deuxième iframe pointer vers quelque chose sur votre propre domaine.

  2. créer une forme cachée, définir sa méthode pour "post" avec cible = votre première iframe, et enctype optionnellement défini à "multipart/form-data" (je pense que vous voulez faire POST parce que vous voulez envoyer des données multipart comme des images?)

  3. Quand vous êtes prêt, faites le formulaire submit () le POST.

  4. si vous pouvez obtenir l'autre domaine pour retourner javascript qui fera la Communication inter-domaines avec Iframes ( http://softwareas.com/cross-domain-communication-with-iframes ) alors vous êtes dans la chance, et vous pouvez capturer la réponse aussi bien.

bien sûr, si vous voulez utiliser votre serveur comme un proxy, vous pouvez éviter tout cela. Simplement soumettez le formulaire à votre propre serveur, qui va proxy la requête à l'autre serveur (en supposant que l'autre serveur n'est pas configuré pour noter les anomalies IP), obtenir la réponse, et retourner ce que vous voulez.

6
répondu Magarshak 2010-03-09 18:13:12
la source

encore Une chose importante à noter!!! Dans exemple ci-dessus, il est décrit comment utiliser

$.ajax({
    type     : 'POST',
    dataType : 'json', 
    url      : 'another-remote-server',
    ...
});

JQuery 1.6 and lower a un bug avec cross-domain XHR. Selon Firebug, aucune demande, sauf OPTIONS, n'a été envoyée. Pas de POST. À tous.

a passé 5 heures à tester / ajuster mon code. Ajout de nombreux en-têtes sur le serveur distant (script). Sans aucun effet. Mais plus tard, J'ai mis JQuery lib à 1.6.4, et tout fonctionne. comme un charme.

6
répondu BasTaller 2017-05-23 15:18:15
la source

si vous voulez faire ceci en ASP.net environnement MVC avec jQuery AJAX, suivez ces étapes: (ceci est un résumé de la solution offerte au ce thread)

supposer que "caller.com" (peut être n'importe quel site Web) doit poster à "server.com" (an ASP.net MVC application)

  1. Sur le "server.com" de l'application Web.config ajouter la section suivante:

      <httpProtocol>
          <customHeaders>
              <add name="Access-Control-Allow-Origin" value="*" />
              <add name="Access-Control-Allow-Headers" value="Content-Type" />
              <add name="Access-Control-Allow-Methods" value="POST, GET, OPTIONS" />
          </customHeaders>
      </httpProtocol>
    
  2. sur le "server.com", nous aurons l'action suivante sur le contrôleur(appelé" Home") auquel nous posterons:

    [HttpPost]
    public JsonResult Save()
    {
        //Handle the post data...
    
        return Json(
            new
            {
                IsSuccess = true
            });
    }
    
  3. Puis de la "caller.com", de publier des données à partir d'un formulaire(avec le html id "formId") "server.com" comme suit:

    $.ajax({
            type: "POST",
            url: "http://www.server.com/home/save",
            dataType: 'json',
            crossDomain: true,
            data: $(formId).serialize(),
            success: function (jsonResult) {
               //do what ever with the reply
            },
            error: function (jqXHR, textStatus) {
                //handle error
            }
        });
    
5
répondu Sujeewa 2017-05-23 15:03:03
la source

de Haut niveau.... Vous devez avoir une configuration cname sur votre serveur pour que other-serve.your-server.com points à retenir other-server.com.

votre page crée dynamiquement une iframe invisible, qui agit comme votre transport vers other-server.com. Vous devez ensuite communiquer via JS à partir de votre page vers le other-server.com et avoir des rappels qui retournent les données à votre page.

Possible mais nécessite une coordination de your-server.com et other-server.com

3
répondu 2009-08-19 22:39:46
la source

C'est une vieille question, mais une nouvelle technologie pourrait aider quelqu'un.

si vous avez un accès administratif à l'autre serveur, alors vous pouvez utiliser le projet de Forge opensource pour accomplir votre poste cross-domain. Forge fournit un wrapper JavaScript XMLHttpRequest cross-domain qui tire profit de L'API de socket raw de Flash. Le POSTE peut même être fait sur TLS.

la raison pour laquelle vous avez besoin d'un accès administratif au serveur que vous affichez to est parce que vous devez fournir une politique inter-domaines qui permet l'accès à partir de votre domaine.

http://github.com/digitalbazaar/forge

3
répondu dlongley 2010-09-23 21:58:06
la source

je pense que la meilleure façon est D'utiliser XMLHttpRequest (e.g. $.Ajax.$ ,)(post () in jQuery) avec un polyfills https://github.com/Modernizr/Modernizr/wiki/HTML5-Cross-Browser-Polyfills#wiki-CORS

3
répondu Roman Dolgiy 2011-10-04 13:49:18
la source

il y a une autre façon (en utilisant la fonctionnalité html5). Vous pouvez utiliser le proxy iframe hébergé sur cet autre domaine, vous envoyez un message en utilisant postMessage à cet iframe, puis que iframe peut faire POST request (sur le même domaine) et postMessage de retour avec reposnse à la fenêtre parent.

parent sur sender.com

var win = $('iframe')[0].contentWindow

function get(event) {
    if (event.origin === "http://reciver.com") {
        // event.data is response from POST
    }
}

if (window.addEventListener){
    addEventListener("message", get, false)
} else {
    attachEvent("onmessage", get)
}
win.postMessage(JSON.stringify({url: "URL", data: {}}),"http://reciver.com");

iframe sur reciver.com

function listener(event) {
    if (event.origin === "http://sender.com") {
        var data = JSON.parse(event.data);
        $.post(data.url, data.data, function(reponse) {
            window.parent.postMessage(reponse, "*");
        });
    }
}
// don't know if we can use jQuery here
if (window.addEventListener){
    addEventListener("message", listener, false)
} else {
    attachEvent("onmessage", listener)
}
3
répondu jcubic 2016-08-14 15:56:02
la source
2
répondu Reddymails 2012-09-28 00:37:47
la source

devrait être possible avec une table personnalisée YQL + JS XHR, jetez un oeil à: http://developer.yahoo.com/yql/guide/index.html

je l'utiliser pour faire des côté client (js) html grattage, fonctionne très bien (J'ai un lecteur audio complet, à la recherche sur internet et/ou de lecture/paroles/last fm d'informations, le client en js + YQL)

1
répondu Guillaume86 2010-08-24 19:59:49
la source

je sais que c'est une vieille question, mais je voulais partager mon approche. J'utilise cURL comme un proxy, très facile et cohérent. Créez une page php appelée submit.php, et ajouter le code suivant:

<?

function post($url, $data) {
$header = array("User-Agent: " . $_SERVER["HTTP_USER_AGENT"], "Content-Type: application/x-www-form-urlencoded");
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
$response = curl_exec($curl);
curl_close($curl);
return $response;
}

$url = "your cross domain request here";
$data = $_SERVER["QUERY_STRING"];
echo(post($url, $data));

puis, dans votre js (jquery ici):

$.ajax({
type: 'POST',
url: 'submit.php',
crossDomain: true,
data: '{"some":"json"}',
dataType: 'json',
success: function(responseData, textStatus, jqXHR) {
    var value = responseData.someKey;
},
error: function (responseData, textStatus, errorThrown) {
    alert('POST failed.');
}
});
1
répondu Ivan Durst 2014-03-06 23:15:41
la source

CORS est pour vous. CORS est "Cross Origin Resource Sharing", c'est une façon d'envoyer des requêtes de domaine croisées.Maintenant, L'API XMLHttpRequest2 et Fetch supporte les deux CORS, et elle peut envoyer les requêtes POST et GET

mais il a ses limites.Le serveur doit spécifier le Access-Control-Allow-Origin , et il ne peut pas être défini à '*'.

et si vous voulez n'importe quelle origine peut vous envoyer la requête, vous avez besoin de JSONP (aussi besoin de définir Access-Control-Allow-Origin , mais peut être'*')

Pour les lots de la demande de façon si tu ne sais pas comment le choix, je pense que vous avez besoin d'un composant fonctionnel de le faire.Permettez-moi d'introduire un composant simple https://github.com/Joker-Jelly/catta


si vous utilisez un navigateur moderne (> IE9, Chrome, FF, Edge, etc.), Très vous recommande d'utiliser un simple mais composant beauté https://github.com/Joker-Jelly/catta .Il n'a pas de dépendance, moins de 3KB, et il supporte Fetch, AJAX et JSONP avec la même syntaxe d'échantillon mortelle et les options.

catta('./data/simple.json').then(function (res) {
  console.log(res);
});

il soutient aussi tout le chemin pour importer à votre projet, comme ES6 module, CommonJS et même <script> en HTML.

1
répondu Jelly 2017-01-23 10:43:36
la source

si vous avez accès au serveur cross domaine et que vous ne voulez pas faire de changement de code du côté du serveur, vous pouvez utiliser une bibliothèque appelée - 'xdomain'.

Comment cela fonctionne:

Étape 1: serveur 1: inclure la bibliothèque xdomain et configurer le domaine croisé comme un esclave:

<script src="js/xdomain.min.js" slave="https://crossdomain_server/proxy.html"></script>

Étape 2: sur le serveur cross domain, créez un proxy.fichier html et inclure le serveur 1 comme maître:

proxy.html:
<!DOCTYPE HTML>
<script src="js/xdomain.min.js"></script>
<script>
  xdomain.masters({
    "https://server1" : '*'
  });
</script>

Step 3:

Maintenant, vous pouvez faire un appel AJAX au mandataire.html comme point de terminaison de server1. C'est contourner la requête de la CORS. La bibliothèque utilise en interne la solution iframe qui fonctionne avec les justificatifs D'identité et toutes les méthodes possibles: GET, POST etc.

Query code ajax:

$.ajax({
        url: 'https://crossdomain_server/proxy.html',
        type: "POST",
        data: JSON.stringify(_data),
        dataType: "json",
        contentType: "application/json; charset=utf-8"
    })
    .done(_success)
    .fail(_failed)
0
répondu Raj Malakpet 2018-09-12 00:27:32
la source

Autres questions sur javascript ajax cross-domain