Я разработал приложение PhoneGap, которое сейчас трансформируется в мобильный сайт. Все работает плавно, кроме одного небольшого глюка. Я использую определенный сторонний API через запрос POST, который отлично работает в приложении, но не работает в мобильной версии веб-сайта.
При более внимательном рассмотрении кажется, что AngularJS (я предполагаю, что браузер) сначала отправляет запрос OPTIONS. Сегодня я многое узнал о CORS, но не могу понять, как его вообще отключить. У меня нет доступа к этому API (поэтому изменения на этой стороне невозможны), но они добавили домен, над которым я работаю, в свой заголовок Access-Control-Allow-Origin.
Это код, о котором я говорю:
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);
});
Как я могу запретить браузеру (или AngularJS) отправлять этот запрос OPTIONS и просто перейти к фактическому запросу POST? Я использую AngularJS 1.2.0.
Заранее спасибо.
Как сказал Рэй, вы можете остановить это, изменив заголовок содержимого, например:
$http.defaults.headers.post["Content-Type"] = "text/plain";
Например -
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'} }); }]);
Или прямо на звонок -
var req = { method: 'POST', url: 'http://example.com', headers: { 'Content-Type': 'text/plain' }, data: { test: 'test' } } $http(req).then(function(){...}, function(){...});
При этом запрос на предполетный вариант не отправляется.
ПРИМЕЧАНИЕ. Запрос не должен иметь никаких настраиваемых параметров заголовка. Если заголовок запроса содержит какой-либо настраиваемый заголовок, браузер сделает предполетный запрос, вы не сможете его избежать.
источник
$http
?GET
и дополнительный заголовокAuthorization
. Но все же предполетная отправка.При выполнении определенных типов междоменных запросов AJAX современные браузеры, поддерживающие CORS, вставляют дополнительный запрос «предварительной проверки», чтобы определить, есть ли у них разрешение на выполнение действия. Из примера запроса:
$http.get( ‘https://example.com/api/v1/users/’ +userId, {params:{ apiKey:’34d1e55e4b02e56a67b0b66’ } } );
В результате этого фрагмента мы видим, что на адрес было отправлено два запроса (OPTIONS и GET). Ответ сервера включает заголовки, подтверждающие допустимость запроса GET. Если ваш сервер не настроен для правильной обработки запроса OPTIONS, клиентские запросы не будут выполнены. Например:
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
источник
Я думаю, что лучший способ - проверить, имеет ли запрос тип "OPTIONS" return 200 из среднего ПО. У меня это сработало.
express.use('*',(req,res,next) =>{ if (req.method == "OPTIONS") { res.status(200); res.send(); }else{ next(); } });
источник
Предварительная проверка - это функция веб-безопасности, реализованная браузером. Для Chrome вы можете отключить всю веб-безопасность, добавив флаг --disable-web-security.
Например: «C: \ Program Files \ Google \ Chrome \ Application \ chrome.exe» --disable-web-security --user-data-dir = «C: \ newChromeSettingsWithoutSecurity». Сначала вы можете создать новый ярлык хрома, перейти к его свойствам и изменить цель, как указано выше. Это должно помочь!
источник
установка типа содержимого на undefined приведет к тому, что javascript будет передавать данные заголовка как есть и перезаписывать конфигурации заголовка angular $ httpProvider по умолчанию. Документация по Angular $ http
$http({url:url,method:"POST", headers:{'Content-Type':undefined}).then(success,failure);
источник