Opracowałem aplikację PhoneGap, która jest obecnie przekształcana w witrynę mobilną. Wszystko działa sprawnie poza jedną małą usterką. Używam interfejsu API innej firmy za pośrednictwem żądania POST, które działa dobrze w aplikacji, ale nie działa w wersji mobilnej strony internetowej.
Po bliższym przyjrzeniu się wydaje się, że AngularJS (wydaje mi się, że faktycznie przeglądarka) najpierw wysyła żądanie OPTIONS. Dowiedziałem się dzisiaj wiele o CORS, ale nie wiem, jak go całkowicie wyłączyć. Nie mam dostępu do tego API (więc zmiany po tej stronie są niemożliwe), ale dodali domenę, nad którą pracuję, do nagłówka Access-Control-Allow-Origin.
Oto kod, o którym mówię:
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);
});
Jak mogę uniemożliwić przeglądarce (lub AngularJS) wysyłanie żądania OPCJI i po prostu przejść do rzeczywistego żądania POST? Używam AngularJS 1.2.0.
Z góry dziękuję.
Jak powiedział Ray, możesz to zatrzymać, modyfikując nagłówek treści, taki jak -
$http.defaults.headers.post["Content-Type"] = "text/plain";
Na przykład -
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'} }); }]);
Lub bezpośrednio na telefon -
var req = { method: 'POST', url: 'http://example.com', headers: { 'Content-Type': 'text/plain' }, data: { test: 'test' } } $http(req).then(function(){...}, function(){...});
Nie spowoduje to wysłania żadnej prośby o opcję przed lotem.
UWAGA: Żądanie nie powinno mieć żadnego niestandardowego parametru nagłówka, jeśli nagłówek żądania zawiera dowolny niestandardowy nagłówek, przeglądarka wykona żądanie przed wysłaniem, nie możesz tego uniknąć.
źródło
$http
?GET
i dodatkowy nagłówekAuthorization
. Ale nadal wysyłam wstępną inspekcję.Podczas wykonywania pewnych typów żądań AJAX międzydomenowych, nowoczesne przeglądarki obsługujące CORS wstawiają dodatkowe żądanie „inspekcji wstępnej” w celu określenia, czy mają uprawnienia do wykonania tej czynności. Z przykładowego zapytania:
$http.get( ‘https://example.com/api/v1/users/’ +userId, {params:{ apiKey:’34d1e55e4b02e56a67b0b66’ } } );
W wyniku tego fragmentu widzimy, że na adres wysłano dwa zapytania (OPCJE i GET). Odpowiedź z serwera zawiera nagłówki potwierdzające dopuszczalność zapytania GET. Jeśli serwer nie jest skonfigurowany do prawidłowego przetwarzania żądania OPTIONS, żądania klientów nie powiodą się. Na przykład:
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
źródło
Myślę, że najlepszym sposobem jest sprawdzenie, czy żądanie jest typu „OPCJE”, zwróć 200 z produktów pośrednich. U mnie to zadziałało.
express.use('*',(req,res,next) =>{ if (req.method == "OPTIONS") { res.status(200); res.send(); }else{ next(); } });
źródło
Inspekcja wstępna to funkcja zabezpieczeń internetowych wdrażana przez przeglądarkę. W przeglądarce Chrome możesz wyłączyć wszystkie zabezpieczenia internetowe, dodając flagę --disable-web-security.
Na przykład: „C: \ Program Files \ Google \ Chrome \ Application \ chrome.exe” --disable-web-security --user-data-dir = „C: \ newChromeSettingsWithoutSecurity”. Możesz najpierw utworzyć nowy skrót do chrome, przejść do jego właściwości i zmienić cel jak wyżej. To powinno pomóc!
źródło
ustawienie typu zawartości na undefined spowodowałoby, że javascript przekazałoby dane nagłówka w takiej postaci, w jakiej jest, i nadpisanie domyślnych konfiguracji kątowych nagłówków $ httpProvider. Dokumentacja Angular $ http
$http({url:url,method:"POST", headers:{'Content-Type':undefined}).then(success,failure);
źródło