Come saltare la richiesta di verifica preliminare OPZIONI in AngularJS

Avevo sviluppato un’app PhoneGap che ora viene trasformata in un sito Web mobile. Tutto funziona senza problemi oltre a un piccolo problema. Uso una determinata API di terze parti tramite una richiesta POST, che funziona bene nell’app, ma non riesce nella versione del sito Web mobile.

Dopo uno sguardo ravvicinato, sembra che AngularJS (suppongo che il browser sia in realtà) prima stia inviando una richiesta OPTIONS. Oggi ho imparato molto su CORS, ma non riesco a capire come disabilitarlo del tutto. Non ho accesso a tale API (quindi i cambiamenti da quel lato sono impossibili), ma hanno aggiunto il dominio su cui sto lavorando alla loro intestazione Access-Control-Allow-Origin.

Questo è il codice di cui sto parlando:

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); }); 

Come posso impedire al browser (o AngularJS) di inviare la richiesta OPTIONS e saltare alla richiesta POST effettiva? Sto usando AngularJS 1.2.0.

Grazie in anticipo.

Il preflight viene triggersto dal tuo Content-Type of application/json . Il modo più semplice per evitare ciò è impostare Content-Type come text/plain nel tuo caso. application/x-www-form-urlencoded e multipart/form-data Content-Type sono accettabili, ma ovviamente dovrai formattare il carico utile della richiesta in modo appropriato.

Se stai ancora vedendo una verifica preliminare dopo aver apportato questa modifica, Angular potrebbe aggiungere anche un’intestazione X alla richiesta.

Come ha detto Ray, puoi fermarlo modificando l’intestazione del contenuto come –

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

Per esempio –

 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'} }); }]); 

O direttamente a una chiamata –

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

Questo non invierà alcuna richiesta di opzione pre-volo.

NOTA: la richiesta non deve avere alcun parametro di intestazione personalizzato. Se l’intestazione della richiesta contiene un’intestazione personalizzata, il browser eseguirà la richiesta di pre-volo, non è ansible evitarlo.

Penso che il modo migliore sia controllare se la richiesta è di tipo “OPTIONS” restituisce 200 dal middleware. Ha funzionato per me.

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

Quando si eseguono determinati tipi di richieste AJAX tra domini, i browser moderni che supportano CORS inseriranno una richiesta supplementare di “preflight” per determinare se hanno il permesso di eseguire l’azione. Dalla query di esempio:

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

Come risultato di questo frammento possiamo vedere che l’indirizzo è stato inviato due richieste (OPZIONI e GET). La risposta dal server include le intestazioni che confermano la permissibilità alla query GET. Se il tuo server non è configurato per elaborare correttamente una richiesta OPTIONS, le richieste del client falliranno. Per esempio:

 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 

impostando il tipo di contenuto su undefined, farebbe in modo che javascript passi i dati dell’intestazione così com’è, e sovrascrivendo le configurazioni dell’intestazione $ httpProvider angular predefinita. Documentazione angular $ http

 $http({url:url,method:"POST", headers:{'Content-Type':undefined}).then(success,failure);