jQuery $.Ajax.$ ,)(post sending "OPTIONS" comme méthode de requête dans Firefox

ayant des problèmes avec ce que je pensais être un plugin jQuery relativement simple...

le plugin doit récupérer les données 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 en Safari. Dans Firefox 3.5, REQUEST_TYPE sur le serveur est toujours "OPTIONS", et les données $_POST n'apparaissent pas. Apache enregistre la requête en tapant 'OPTIONS':

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

pourquoi cet appel ajax fonctionnerait-il en Safari, mais pas en Firefox, et comment puis-je le réparer pour Firefox?

Response Headers
Date: Wed, 08 Jul 2009 21:22:17 GMT
Server:Apache/2.0.59 (Unix) PHP/5.2.6 DAV/2
X-Powered-By: PHP/5.2.6
Content-Length  46
Keep-Alive  timeout=15, max=100
Connection  Keep-Alive
Content-Type    text/html

Request Headers
Host    orderform:8888
User-Agent  Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10.5; en-US; rv:1.9.1) Gecko/20090624 Firefox/3.5
Accept  text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language en-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
Origin  http://ux.inetu.act.org
Access-Control-Request-Method   POST
Access-Control-Request-Headers  x-requested-with

Voici une image de la sortie Firebug:

314
demandé sur VisioN 2009-07-08 22:26:00

23 réponses

La raison de l'erreur est la même origine. Il vous permet seulement de faire des requêtes XMLHTTP à votre propre domaine. Voir si vous pouvez utiliser un JSONP callback à la place:

$.getJSON( 'http://<url>/api.php?callback=?', function ( data ) { alert ( data ); } );
165
répondu Jonas Skovmand 2012-12-27 00:10:32

j'ai utilisé le code suivant du côté de Django pour interpréter la requête D'OPTIONS et pour régler les en-têtes de contrôle d'accès nécessaires. Après cela, mes requêtes de domaine croisées de Firefox ont commencé à fonctionner. Comme dit avant, le navigateur envoie d'abord la demande D'OPTIONS et 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":
        # ... 

éditer: il semble qu'au moins dans certains cas, vous devez également ajouter les mêmes en-têtes de contrôle d'accès à la réponse réelle. Cela peut être un peu un peu confus, puisque la requête semble réussir, mais Firefox ne transmet pas le contenu de la réponse au Javascript.

55
répondu Juha Palomäki 2012-10-10 14:29:34

Ce 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' devrait être envoyée comme une 'requête simple' (Sans option 'preflight'). 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 pu faire ce travail en créant un options request handler sur le serveur, qui définit l'en-tête de réponse' Access-Control-Allow-Origin 'à'*'. Vous pouvez être plus restrictif en le mettant à quelque chose de spécifique, comme ' http://someurl.com " Aussi, j'ai lu que, soi-disant, Vous pouvez spécifier une liste de plusieurs origines séparées par des virgules, Mais je n'ai pas pu faire que cela fonctionne.

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

16
répondu Mike C 2010-05-19 13:32:49

j'ai corrigé ce problème en utilisant une solution entièrement basée sur Apache. Dans mon vhost / htaccess j'ai mis le bloc suivant:

# enable cross domain access control
Header always set Access-Control-Allow-Origin "*"
Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS"

# force apache to return 200 without executing my scripts
RewriteEngine On
RewriteCond %{REQUEST_METHOD} OPTIONS
RewriteRule .* / [R=200,L]

il se peut que vous n'ayez pas besoin de cette dernière partie, selon ce qui se passe quand Apache exécute votre script cible. Le crédit va au serverfault Folk amical pour la dernière partie.

15
répondu Mark McDonald 2017-04-13 12:13:35

ce PHP en haut du script de réponse semble fonctionner. (Avec Firefox 3.6.11. Je n'ai pas encore fait beaucoup de tests.)

header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: POST, GET, OPTIONS');
header('Access-Control-Max-Age: 1000');
if(array_key_exists('HTTP_ACCESS_CONTROL_REQUEST_HEADERS', $_SERVER)) {
    header('Access-Control-Allow-Headers: '
           . $_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']);
} else {
    header('Access-Control-Allow-Headers: *');
}

if("OPTIONS" == $_SERVER['REQUEST_METHOD']) {
    exit(0);
}
10
répondu Chad Clark 2010-10-28 20:56:57

j'ai eu le même problème avec l'envoi de demandes à google maps, et la solution est assez simple avec jQuery 1.5 - Pour l'utilisation de type de données dataType: "jsonp"

7
répondu Slavomir 2011-02-10 02:40:03

coupable est une demande avant le vol en utilisant la méthode des OPTIONS

pour les méthodes de requête HTTP qui peuvent causer des effets secondaires sur les données de l'utilisateur( en particulier, pour les méthodes HTTP autres que GET, ou pour la POST-utilisation avec certains types MIME), la spécification prescrit que les navigateurs "préviennent" la requête, sollicitant les méthodes prises en charge par le serveur avec une méthode de requête D'OPTIONS HTTP, puis, sur "approbation" du serveur, en envoyant la requête réelle avec la requête HTTP réelle méthode.

Web spécification de se référer à: https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS

j'ai résolu le problème en ajoutant les lignes suivantes dans nginx conf.

    location / {
               if ($request_method = OPTIONS ) {
                   add_header Access-Control-Allow-Origin  "*";
                   add_header Access-Control-Allow-Methods "POST, GET, PUT, UPDATE, DELETE, OPTIONS";
                   add_header Access-Control-Allow-Headers "Authorization";
                   add_header Access-Control-Allow-Credentials  "true";
                   add_header Content-Length 0;
                   add_header Content-Type text/plain;
                   return 200;
               }
    location ~ ^/(xxxx)$ {
                if ($request_method = OPTIONS) {
                    rewrite ^(.*)$ / last;
                }
    }
5
répondu thinkhy 2016-04-22 15:04:47

je regardais à travers la source 1.3.2, en utilisant JSONP, la demande est faite en construisant un élément de SCRIPT dynamiquement, qui passe les navigateurs même-Politique de domaine. Naturellement, vous ne pouvez pas faire une requête POST en utilisant un élément SCRIPT, le navigateur récupérerait le résultat en utilisant GET.

comme vous demandez un appel JSONP, L'élément SCRIPT n'est pas généré, car il ne le fait que lorsque le Type D'appel AJAX est défini pour obtenir.

http://dev.jquery.com/ticket/4690

4
répondu 2009-09-22 19:51:10

nous avons eu un problème comme celui-ci avec ASP.Net. Notre IIS retournait une erreur de serveur interne en essayant d'exécuter un jQuery $.post pour obtenir du contenu html dû à PageHandlerFactory était limité à répondre seulement GET,HEAD,POST,DEBUG verbes. Vous pouvez donc modifier cette restriction en ajoutant le verbe "OPTIONS" à la liste ou en sélectionnant" Tous les verbes "

vous pouvez modifier cela dans votre IIS Manager, en sélectionnant votre site web, puis en sélectionnant Handler Mappings, double-cliquez dans votre PageHandlerFactory for *.fichiers apx selon vos besoins (nous utilisons le pool d'applications intégré avec framework 4.0). Cliquez sur Request Restrictions, puis allez à Verbs Tabn et appliquez votre modification.

maintenant notre demande $.post fonctionne comme prévu :)

3
répondu fboiton 2013-01-22 15:00:56

vérifiez si L'URL action de votre formulaire inclut la partie www du domaine, alors que la page originale que vous avez ouverte est vue sans www .

typiquement fait pour les Urls canoniques..

j'ai lutté pendant des heures avant de tomber sur cet article et j'ai trouvé l'allusion de Cross Domain.

2
répondu Bijay Rungta 2011-04-20 09:09:19

il me semble que si o.url = 'index.php' et que ce fichier existe est ok et renvoie un message de succès dans la console. Il retourne une erreur si j'utilise l'url: http://www.google.com

si vous faites une requête post pourquoi ne pas utiliser directement le $.post méthode:

$.post("test.php", { func: "getNameAndTime" },
    function(data){
        alert(data.name); // John
        console.log(data.time); //  2pm
    }, "json");

C'est tellement plus simple.

2
répondu Elzo Valugi 2013-01-22 14:57:24

j'ai posté un exemple clair de la façon de résoudre ceci si contrôler le code du serveur du domaine dans lequel vous postez. Cette réponse est abordée dans ce fil, mais cela l'explique plus clairement IMO.

Comment puis-je envoyer une demande postale trans-domaine via JavaScript?

1
répondu rynop 2017-05-23 11:47:23

Solution à cette question est:

  1. utiliser le type de données: json
  2. ajouter &callback=? à votre url

cela a fonctionné sur l'appel de L'API Facebook et avec Firefox. Firebug utilise GET au lieu de OPTIONS avec les conditions ci-dessus (les deux).

1
répondu Antonio Gulli 2012-01-05 16:46:49

une autre possibilité pour contourner le problème est d'utiliser un script proxy. Cette méthode est décrite pour exemple ici

1
répondu Niehztog 2013-01-22 14:59:33

Pouvez-vous l'essayer sans

contentType:application/x-www-form-urlencoded

0
répondu Mathias F 2009-07-08 18:40:12

essayez d'ajouter l'option:

type de données:" json "

0
répondu ScottE 2009-07-10 12:51:32
 function test_success(page,name,id,divname,str)
{ 
 var dropdownIndex = document.getElementById(name).selectedIndex;
 var dropdownValue = document.getElementById(name)[dropdownIndex].value;
 var params='&'+id+'='+dropdownValue+'&'+str;
 //makerequest_sp(url, params, divid1);

 $.ajax({
    url: page,
    type: "post",
    data: params,
    // callback handler that will be called on success
    success: function(response, textStatus, jqXHR){
        // log a message to the console
        document.getElementById(divname).innerHTML = response;

        var retname = 'n_district';
        var dropdownIndex = document.getElementById(retname).selectedIndex;
        var dropdownValue = document.getElementById(retname)[dropdownIndex].value;
        if(dropdownValue >0)
        {
            //alert(dropdownValue);
            document.getElementById('inputname').value = dropdownValue;
        }
        else
        {
            document.getElementById('inputname').value = "00";
        }
        return;
        url2=page2; 
        var params2 = parrams2+'&';
        makerequest_sp(url2, params2, divid2);

     }
});         
}
0
répondu Naser Gulzade 2013-01-01 10:26:28

j'ai eu un problème similaire en essayant d'utiliser L'API Facebook.

le seul type de contenu qui n'a pas envoyé la demande pré-éclairée semble être juste text/plain... pas le reste des paramètres mentionnés à mozilla ici

  • Pourquoi est-ce le seul navigateur qui fait cela?
  • pourquoi Facebook ne sait - il pas et n'accepte-t-il pas la demande avant le vol?

FYI: Le Moz doc susmentionné suggère que les en-têtes X-Lori devraient déclencher une requête pré-allumée ... ça ne l'est pas.

0
répondu Drew 2013-01-22 14:57:33

vous devez faire un peu de travail du côté du serveur. Je vois que vous utilisez PHP du côté du serveur, mais la solution pour L'application web .NET est ici: ne peut pas définir le type de contenu à 'application/json' dans jQuery.ajax

faites la même chose dans le script PHP et ça marchera. Simplement: à la première demande le navigateur demande au serveur si est autorisé à envoyer de telles données avec un tel type et la deuxième demande est le bon / autorisé.

0
répondu Fanda 2017-05-23 12:03:02

essayez d'ajouter ce qui suit:

dataType: "json",
ContentType: "application/json",
data: JSON.stringify({"method":"getStates", "program":"EXPLORE"}),  
0
répondu Mary Jain 2014-06-09 13:22:48

j'ai utilisé une url proxy pour résoudre un problème similaire lorsque je veux poster des données sur mon apache solr hébergé sur un autre serveur. (Cela peut ne pas être la réponse parfaite, mais elle n'en résout mon problème.)

suivez cette URL: en utilisant le Mode-Rewrite pour , j'ajoute cette ligne à mon httpd.conf:

 RewriteRule ^solr/(.*)$ http://ip:8983/solr [P]

par conséquent, je peux simplement poster des données à / solr au lieu de poster des données à http://ip:8983/solr / *. Puis il affichera les données dans la même origine.

0
répondu Bernice 2015-07-21 08:13:57

j'ai déjà ce code qui gère bien Ma situation cors en php:

header( 'Access-Control-Allow-Origin: '.CMSConfig::ALLOW_DOMAIN );
header( 'Access-Control-Allow-Headers: '.CMSConfig::ALLOW_DOMAIN );
header( 'Access-Control-Allow-Credentials: true' );

et il fonctionnait bien localement et à distance, mais pas pour les uploads à distance.

quelque chose se passe avec apache/php ou mon code, je n'ai pas pris la peine de le rechercher, quand vous demandez des OPTIONS il renvoie mon en-tête avec les règles cors mais avec 302 résultat. Par conséquent, mon navigateur ne reconnaît pas comme une situation acceptable.

ce que j'ai fait, basé sur @Mark McDonald réponse, est juste mettre ce code après mon en-tête:

if( $_SERVER['REQUEST_METHOD'] === 'OPTIONS' )
{
    header("HTTP/1.1 202 Accepted");
    exit;
}

Maintenant, lorsque vous demandez OPTIONS il vous suffit d'envoyer l'en-tête et 202 résultat.

0
répondu Orlando Leite 2017-03-15 15:14:35

s'il vous Plaît noter:

JSONP supporte uniquement la méthode GET request.

*Envoyer la demande par la firefox :*

$.ajax({
   type: 'POST',//<<===
   contentType: 'application/json',
   url: url,
   dataType: "json"//<<=============
    ...
});

ci-dessus Demande envoyée par OPTIONS (while ==> type: 'POST' )!!!!

$.ajax({
    type: 'POST',//<<===
    contentType: 'application/json',
    url: url,
    dataType: "jsonp"//<<==============
    ...
});

mais au-dessus de la demande envoyer par GET (while = = > type: 'POST' )!!!!

lorsque vous êtes en "communication inter-domaines", faites attention et soyez prudent.

-1
répondu M.Namjo 2017-02-01 15:47:06