Como pular a solicitação de preflight do OPTIONS em AngularJS

Eu desenvolvi um aplicativo PhoneGap que agora está sendo transformado em um site para celular. Tudo funciona bem, além de uma pequena falha. Eu uso uma determinada API de terceiros por meio de uma solicitação POST, que funciona bem no aplicativo, mas falha na versão do website para dispositivos móveis.

Depois de um olhar mais atento, parece que o AngularJS (acho que o navegador realmente) está enviando uma solicitação OPTIONS. Eu aprendi muito hoje sobre o CORS, mas não consigo descobrir como desativá-lo completamente. Eu não tenho access a essa API (portanto, as alterações nesse lado são impossíveis), mas elas adicionaram o domínio no qual estou trabalhando em seu header Access-Control-Allow-Origin.

Este é o código que estou falando:

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

Como posso evitar que o navegador (ou AngularJS) envie essa solicitação OPTIONS e simplesmente pule para a solicitação POST real? Eu estou usando o AngularJS 1.2.0.

Desde já, obrigado.

O preflight está sendo acionado pelo seu Content-Type of application/json . A maneira mais simples de evitar isso é definir o Content-Type como text/plain no seu caso. application/x-www-form-urlencoded & multipart/form-data Content-Types também são aceitáveis, mas é claro que você precisa formatar adequadamente sua carga útil de solicitação.

Se você ainda estiver vendo uma pré-impressão depois de fazer essa alteração, o Angular também poderá adicionar um header X à solicitação.

Como o Ray disse, você pode pará-lo modificando o header do conteúdo como:

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

Por exemplo –

 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 diretamente para uma chamada –

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

Isso não enviará qualquer solicitação de opção pré-flight.

OBSERVAÇÃO: A solicitação não deve ter nenhum parâmetro de header personalizado. Se o header da solicitação contiver um header personalizado, o navegador fará uma solicitação de pré-vôo. Você não poderá evitá-lo.

Acho que a melhor maneira é verificar se o pedido é do tipo “OPÇÕES”, retornar 200 do item médio. Isso funcionou para mim.

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

Ao executar determinados tipos de solicitações AJAX de vários domínios, os navegadores modernos que oferecem suporte ao CORS inserem uma solicitação extra de “comprovação” para determinar se eles têm permissão para executar a ação. Da consulta de exemplo:

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

Como resultado deste fragment, podemos ver que o endereço foi enviado dois pedidos (OPTIONS e GET). A resposta do servidor inclui headers confirmando a permissibilidade da consulta GET. Se o seu servidor não estiver configurado para processar uma solicitação OPTIONS corretamente, as solicitações do cliente falharão. Por exemplo:

 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 

configurar o tipo de conteúdo para undefined faria o javascript transmitir os dados do header Como estão, e gravar as configurações padrão do header $ httpProvider angular. Documentação Angular $ http

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