web-dev-qa-db-fra.com

Comment ignorer la demande de contrôle en amont d'OPTIONS?

J'avais développé une application PhoneGap qui est en train de devenir un site Web mobile. Tout fonctionne bien à part un petit problème. J'utilise une API tierce via une requête POST, qui fonctionne correctement dans l'application, mais échoue dans la version du site Web mobile.

Après un examen plus approfondi, il semble que AngularJS (en fait, je suppose que le navigateur) envoie d’abord une demande OPTIONS. Aujourd'hui, j'ai beaucoup appris sur la CORS, mais je n'arrive pas à comprendre comment le désactiver. Je n'ai pas accès à cette API (les modifications de ce côté sont donc impossibles), mais ils ont ajouté le domaine sur lequel je travaille à leur en-tête Access-Control-Allow-Origin.

C'est le code dont je parle:

        var request = {
                language: 'fr',
                barcodes: [
                    {
                        barcode: 'somebarcode',
                        description: 'Description goes here'
                    }
                ]
            };
        }
        var config = {
            headers: { 
                'Cache-Control': 'no-cache',
                'Content-Type': 'application/json'
            }
        };
        $http.post('http://somedomain.be/trackinginfo', request, config).success(function(data, status) {
            callback(undefined, data);
        }).error(function(data, status) {
            var err = new Error('Error message');
            err.status = status;
            callback(err);
        });

Comment puis-je empêcher le navigateur (ou AngularJS) d’envoyer cette demande OPTIONS et de passer directement à la demande POST actuelle? J'utilise AngularJS 1.2.0.

Merci d'avance.

81
Bram Vandewalle

Le contrôle en amont est déclenché par votre type de contenu de application/json. Le moyen le plus simple d'éviter cela consiste à définir le type de contenu sur text/plain dans votre cas. application/x-www-form-urlencoded & multipart/form-data Les types de contenu sont également acceptables, mais vous aurez évidemment besoin de formater votre charge utile de manière appropriée.

Si vous voyez toujours un contrôle en amont après avoir effectué cette modification, alors Angular peut également ajouter un en-tête X à la demande.

Ou vous pouvez avoir des en-têtes (Authorization, Cache-Control ...) qui vont le déclencher, voir:

97
Ray Nicholus

Comme ce que Ray a dit, vous pouvez l'arrêter en modifiant l'en-tête de contenu comme -

 $http.defaults.headers.post["Content-Type"] = "text/plain";

Par exemple -

angular.module('myApp').factory('User', ['$resource','$http',
    function($resource,$http){
        $http.defaults.headers.post["Content-Type"] = "text/plain";
        return $resource(API_ENGINE_URL+'user/:userId', {}, {
            query: {method:'GET', params:{userId:'users'}, isArray:true},
            getLoggedIn:{method:'GET'}
        });
    }]);

Ou directement à un appel -

var req = {
 method: 'POST',
 url: 'http://example.com',
 headers: {
   'Content-Type': 'text/plain'
 },
 data: { test: 'test' }
}

$http(req).then(function(){...}, function(){...});

Cela n'enverra aucune demande d'option pré-vol.

NOTE: La requête ne doit avoir aucun paramètre d'en-tête personnalisé. Si l'en-tête de requête contient un en-tête personnalisé, le navigateur fera une demande de pré-vol, vous ne pourrez pas l'éviter.

13
Vivek

Je pense que le meilleur moyen est de vérifier si la requête est du type "OPTIONS" retour 200 du middleware. Cela a fonctionné pour moi.

express.use('*',(req,res,next) =>{
      if (req.method == "OPTIONS") {
        res.status(200);
        res.send();
      }else{
        next();
      }
    });
2

Lors de l'exécution de certains types de demandes interdomaines AJAX, les navigateurs modernes prenant en charge CORS insèrent une demande supplémentaire de "contrôle en amont" afin de déterminer s'ils sont autorisés à effectuer l'action. Exemple de requête:

$http.get( ‘https://example.com/api/v1/users/’ +userId,
  {params:{
           apiKey:’34d1e55e4b02e56a67b0b66’
          }
  } 
);

À la suite de ce fragment, nous pouvons voir que l'adresse a été envoyée à deux demandes (OPTIONS et GET). La réponse du serveur comprend des en-têtes confirmant la validité de la requête GET. Si votre serveur n'est pas configuré pour traiter correctement une demande OPTIONS, les demandes du client échoueront. Par exemple:

Access-Control-Allow-Credentials: true
Access-Control-Allow-Headers: accept, Origin, x-requested-with, content-type
Access-Control-Allow-Methods: DELETE
Access-Control-Allow-Methods: OPTIONS
Access-Control-Allow-Methods: PUT
Access-Control-Allow-Methods: GET
Access-Control-Allow-Methods: POST
Access-Control-Allow-Orgin: *
Access-Control-Max-Age: 172800
Allow: PUT
Allow: OPTIONS
Allow: POST
Allow: DELETE
Allow: GET
1
M.Void

Le contrôle en amont est une fonctionnalité de sécurité Web mise en œuvre par le navigateur. Pour Chrome, vous pouvez désactiver toute la sécurité Web en ajoutant l'indicateur --disable-web-security.

Par exemple: "C:\Programmes\Google\Chrome\Application\chrome.exe" --disable-web-security --user-data-dir = "C:\newChromeSettingsWithoutSecurity". Vous pouvez d'abord créer un nouveau raccourci de chrome, accéder à ses propriétés et modifier la cible comme ci-dessus. Cela devrait aider!

0
Arijit Patra