Une requête POST de CORS fonctionne à partir de javascript, mais pourquoi pas avec jQuery?

j'essaie de faire une demande de courrier D'origine croisée, et je l'ai obtenu en Javascript simple comme ceci:

var request = new XMLHttpRequest();
var params = "action=something";
request.open('POST', url, true);
request.onreadystatechange = function() {if (request.readyState==4) alert("It worked!");};
request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
request.setRequestHeader("Content-length", params.length);
request.setRequestHeader("Connection", "close");
request.send(params);

Mais je voudrais utiliser jQuery, mais je ne peux pas le faire fonctionner. C'est ce que j'essaie:

$.ajax(url, {
    type:"POST",
    dataType:"json",
    data:{action:"something"}, 
    success:function(data, textStatus, jqXHR) {alert("success");},
    error: function(jqXHR, textStatus, errorThrown) {alert("failure");}
});

il en résulte un échec. Si quelqu'un sait pourquoi jQuery ne fonctionne pas, veuillez nous le savons tous. Grâce.

(j'utilise jQuery 1.5.1, et Firefox 4.0, et mon serveur répond avec un bon Access-Control-Allow-Origin header)

74
demandé sur mateusmaso 2011-04-07 21:12:01

3 réponses

mise à jour: comme TimK l'a souligné, ce n'est plus nécessaire avec jquery 1.5.2. Mais si vous souhaitez ajouter des en-têtes personnalisés ou Autoriser l'utilisation de justificatifs d'identité (nom d'utilisateur, mot de passe, cookies, etc.), lisez la suite.


je pense que j'ai trouvé la réponse! (4 heures et beaucoup de jurons plus tard)

//This does not work!!
Access-Control-Allow-Headers: *

vous devez spécifier manuellement tous les en-têtes que vous accepterez (au moins C'était le cas pour moi dans FF 4.0 & Chrome 10.0.648.204).

de jQuery $.la méthode ajax envoie l'en-tête" X-requested-with " pour toutes les requêtes de domaines croisés (je pense que c'est son seul domaine croisé).

ainsi l'en-tête manquant nécessaire pour répondre à la requête D'OPTIONS est:

//no longer needed as of jquery 1.5.2
Access-Control-Allow-Headers: x-requested-with

si vous dépassez des en-têtes non "simples", vous devrez les inclure dans votre liste (j'en envoie une de plus):

//only need part of this for my custom header
Access-Control-Allow-Headers: x-requested-with, x-requested-by

donc pour mettre tout cela ensemble, voici mon PHP:

// * wont work in FF w/ Allow-Credentials
//if you dont need Allow-Credentials, * seems to work
header('Access-Control-Allow-Origin: http://www.example.com');
//if you need cookies or login etc
header('Access-Control-Allow-Credentials: true');
if ($this->getRequestMethod() == 'OPTIONS')
{
  header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS');
  header('Access-Control-Max-Age: 604800');
  //if you need special headers
  header('Access-Control-Allow-Headers: x-requested-with');
  exit(0);
}
63
répondu Will Mason 2011-04-21 00:48:54

une autre possibilité est que le paramètre dataType: json provoque JQuery à envoyer l'en-tête Content-Type: application/json . CORS considère qu'il s'agit d'un en-tête non standard et exige une demande de pré-vol du CORS. Donc quelques choses à essayer:

1) Essayez de configurer votre serveur pour qu'il envoie les réponses pré-vol appropriées. Ce sera sous la forme d'en-têtes supplémentaires comme Access-Control-Allow-Methods et Access-Control-Allow-Headers .

2) Laisser tomber le réglage dataType: json . JQuery devrait demander Content-Type: application/x-www-form-urlencoded par défaut, mais juste pour être sûr, vous pouvez remplacer dataType: json avec contentType: 'application/x-www-form-urlencoded'

16
répondu monsur 2011-04-08 01:33:14

vous envoyez "params" en js: request.send(params);

mais "données" en jquery". Des données est-elle définie?: data:data,

vous avez aussi une erreur dans L'URL:

$.ajax( {url:url,
         type:"POST",
         dataType:"json",
         data:data, 
         success:function(data, textStatus, jqXHR) {alert("success");},
         error: function(jqXHR, textStatus, errorThrown) {alert("failure");}
});

vous mélangez la syntaxe avec celle de $.post


mise à jour : Je googlais autour basé sur la réponse de monsur, et j'ai trouvé que vous devez ajouter Access-Control-Allow-Headers: Content-Type (ci-dessous est le paragraphe complet)

http://metajack.im/2010/01/19/crossdomain-ajax-for-xmpp-http-binding-made-easy /

Comment la SCRO Œuvres

CORS fonctionne très similaire à Flash crossdomain.fichier xml. Fondamentalement, l' navigateur enverra un cross-domaine demande à un service, paramétrage du HTTP origine de l'en-tête à la requête serveur. Le service comprend quelques les en-têtes comme Access-Control-Allow-Origin pour indiquer si une telle demande est permettre.

pour les directeurs de connexion BOSH, il suffit de spécifier que toutes les origines sont autorisés, en fixant la valeur de Access-Control-Allow-Origin to *. Le -Tête Content-Type doit également être la liste blanche dans le En-tête Access-Control-Allow-Headers.

enfin, pour certains types de demandes, y compris connexion BOSH le gestionnaire de demandes, les autorisations vérifiez les pré-flighted. Le le navigateur va faire une demande D'OPTIONS et recevoir des en-têtes HTTP qui indiquent quelles origines sont autorisé, quelles méthodes sont autorisées, et combien de temps cette autorisation Dernière. Par exemple, voici ce que l' J'ai fait des patchs Punjab et ejabberd. retour à OPTIONS:

Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: Content-Type 
Access-Control-Max-Age: 86400
8
répondu Aleadam 2011-04-09 17:03:01