angularjs - llenar - ng-options filter
Cómo omitir la solicitud de verificación previa de OPTIONS en AngularJS (5)
Desarrollé una aplicación PhoneGap que ahora se está transformando en un sitio web móvil. Todo funciona sin problemas, además de un pequeño problema. Utilizo cierta API de terceros a través de una solicitud POST, que funciona bien en la aplicación, pero falla en la versión del sitio web para dispositivos móviles.
Después de una mirada más cercana, parece que AngularJS (supongo que el navegador realmente) está enviando primero una solicitud de OPCIONES. Aprendí mucho sobre CORS, pero parece que no puedo descubrir cómo desactivarlo por completo. No tengo acceso a esa API (por lo que los cambios en ese lado son imposibles), pero han agregado el dominio en el que estoy trabajando a su encabezado Access-Control-Allow-Origin.
Este es el código del que estoy hablando:
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);
});
¿Cómo puedo evitar que el navegador (o AngularJS) envíe esa solicitud de OPCIONES y salte a la solicitud de POST real? Estoy usando AngularJS 1.2.0.
Gracias por adelantado.
Al realizar ciertos tipos de solicitudes AJAX de dominios cruzados, los navegadores modernos que admiten CORS insertan una solicitud extra de "verificación previa" para determinar si tienen permiso para realizar la acción. De consulta de ejemplo:
$http.get( ‘https://example.com/api/v1/users/’ +userId,
{params:{
apiKey:’34d1e55e4b02e56a67b0b66’
}
}
);
Como resultado de este fragmento, podemos ver que a la dirección se le enviaron dos solicitudes (OPCIONES y OBTENCIÓN). La respuesta del servidor incluye encabezados que confirman la permisibilidad de la consulta GET. Si su servidor no está configurado para procesar correctamente una solicitud OPTIONS, las solicitudes de los clientes fallarán. Por ejemplo:
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
Como dijo Ray, puedes detenerlo modificando el encabezado de contenido como ...
$http.defaults.headers.post["Content-Type"] = "text/plain";
Por ejemplo -
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 directamente a una llamada -
var req = {
method: ''POST'',
url: ''http://example.com'',
headers: {
''Content-Type'': ''text/plain''
},
data: { test: ''test'' }
}
$http(req).then(function(){...}, function(){...});
Esto no enviará ninguna solicitud de opción previa al vuelo.
NOTA: La solicitud no debe tener ningún parámetro de encabezado personalizado. Si el encabezado de solicitud contiene un encabezado personalizado, el navegador realizará la solicitud previa al vuelo, no puede evitarlo.
Creo que la mejor manera es verificar si la solicitud es de tipo "OPCIONES" devolver 200 de middle ware. Funcionó para mí
express.use(''*'',(req,res,next) =>{
if (req.method == "OPTIONS") {
res.status(200);
res.send();
}else{
next();
}
});
La comprobación previa está siendo activada por su tipo de contenido application/json
. La forma más sencilla de evitar esto es configurar el tipo de contenido como text/plain
en su caso. application/x-www-form-urlencoded
y multipart/form-data
Los tipos de contenido también son aceptables, pero por supuesto necesitará formatear la carga útil de su solicitud de forma adecuada.
Si todavía está viendo una verificación previa después de hacer este cambio, Angular puede agregar un encabezado X a la solicitud también.
establecer el tipo de contenido en indefinido haría que javascript pase los datos del encabezado tal como están y al escribir las configuraciones predeterminadas del encabezado angular $ httpProvider. Documentación Angular $ http
$http({url:url,method:"POST", headers:{''Content-Type'':undefined}).then(success,failure);