335 votes

jQuery $.ajax(), $.post envoyant des « OPTIONS » comme REQUEST_METHOD dans Firefox

La difficulté avec ce que je pensais était relativement simple plugin jQuery...

Le plugin doit extraire des données à partir d'un script php via ajax pour ajouter des options à un <select>. La requête ajax est assez générique:

$.ajax({
  url: o.url,
  type: 'post',
  contentType: "application/x-www-form-urlencoded",
  data: '{"method":"getStates", "program":"EXPLORE"}',
  success: function (data, status) {
    console.log("Success!!");
    console.log(data);
    console.log(status);
  },
  error: function (xhr, desc, err) {
    console.log(xhr);
    console.log("Desc: " + desc + "\nErr:" + err);
  }
});

Cela semble bien fonctionner dans Safari. Dans Firefox 3.5, l' REQUEST_TYPE sur le serveur est toujours "OPTIONS", et le $_POST les données n'apparaissent pas. Logs Apache en tant que demande de type "OPTIONS":

::1 - - [08/Jul/2009:11:43:27 -0500] "OPTIONS sitecodes.php HTTP/1.1" 200 46

Pourquoi en serait-il appel ajax travail dans Safari, mais pas Firefox, et comment dois-je faire pour Firefox?

En-Têtes De Réponse
Date: Wed, 08 Jul 2009 21:22:17 GMT
Serveur:Apache/2.0.59 (Unix) PHP/5.2.6 DAV/2
X-Powered-By: PHP/5.2.6
Contenu-Durée 46
Keep-Alive timeout=15, max=100
Connection Keep-Alive
Content-Type text/html

En-Têtes De Requête
Accueil bon de commande à:8888
L'Agent utilisateur de Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1) Gecko/20090624 Firefox/3.5
Accepter text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language fr-us,en;q=0.5
Accept-Encoding gzip,deflate
Accept-Charset ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive 300
Connection keep-alive
Origine http://ux.inetu.act.org
Contrôle d'accès-Demande-Méthode POST
Contrôle d'accès-Demande-en-Têtes x-requested-with

Voici une photo de l'Firebug de sortie:

170voto

Jonas Skovmand Points 1394

La raison de l’erreur est la même politique d’origine. Il permet seulement d’effectuer XMLHTTPRequests à votre propre nom de domaine. Voir si vous pouvez utiliser un rappel JSONP plutôt :

57voto

Juha Palomäki Points 7216

J'ai utilisé le code suivant sur Django côté d'interpréter la demande d'OPTIONS et le Contrôle d'Accès des en-têtes. Après cela, ma croix de domaine de demandes de Firefox a commencé à travailler. Comme dit avant, le navigateur envoie d'abord la demande d'OPTIONS, puis immédiatement après que le POST/GET

def send_data(request):
    if request.method == "OPTIONS": 
        response = HttpResponse()
        response['Access-Control-Allow-Origin'] = '*'
        response['Access-Control-Allow-Methods'] = 'POST, GET, OPTIONS'
        response['Access-Control-Max-Age'] = 1000
        # note that '*' is not valid for Access-Control-Allow-Headers
        response['Access-Control-Allow-Headers'] = 'origin, x-csrftoken, content-type, accept'
        return response
    if request.method == "POST":
        # ... 

Edit: il semble que, au moins dans certains cas, vous devez également ajouter le même Contrôle d'Accès des en-têtes de la réponse réelle. Cela peut être un peu de confusion, car la demande semble réussir, mais Firefox ne passe pas le contenu de la réponse à la Javascript.

17voto

Mike C Points 2197

Cette mozilla developer center article décrit les différentes croix-demande de domaine scénarios. L'article semble indiquer qu'une requête POST avec le type de contenu 'application/x-www-form-urlencoded' doit être envoyé comme simple demande "(pas de "contrôle en amont" OPTIONS de demande). J'ai trouvé , cependant, que Firefox a envoyé la demande d'OPTIONS, même si mon message a été envoyé avec ce type de contenu.

J'ai été capable de faire ce travail par la création d'un gestionnaire de requêtes sur le serveur, le jeu de la "Access-Control-Allow-Origin' en-tête de réponse à '*'. Vous pouvez être plus restrictive, en mettant quelque chose de spécifique, comme "http://someurl.com'. Aussi, j'ai lu que, soi-disant, vous pouvez spécifier une liste séparée par des virgules des origines multiples, mais je ne pouvais pas obtenir que cela fonctionne.

Une fois Firefox reçoit la réponse à la demande d'OPTIONS avec une acceptables "Access-Control-Allow-Origin' valeur, il envoie une requête POST.

15voto

Mark McDonald Points 2503

J’ai fixé ce problème à l’aide d’une solution entièrement Apache-basé. Dans mon vhost / bloquer htaccess j’ai mis ce qui suit :

Vous devrez ne peut-être pas la dernière partie, selon ce qui arrive quand Apache s’exécute votre script cible. Le crédit va à l' amicale ServerFault folk pour la dernière partie.

10voto

Chad Clark Points 168

Ce PHP en haut du script ayant répondu au questionnaire semble fonctionner. (Avec Firefox 3.6.11. Je n'ai pas encore fait beaucoup de tests.)

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