나는 현재 모바일 웹 사이트로 변환되는 PhoneGap 앱을 개발했습니다. 작은 결함 하나 외에 모든 것이 원활하게 작동합니다. 앱에서는 제대로 작동하지만 모바일 웹 사이트 버전에서는 실패하는 POST 요청을 통해 특정 타사 API를 사용합니다.
자세히 살펴보면 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을 사용하고 있습니다.
미리 감사드립니다.
답변
프리 플라이트는 Content-Type의 application/json
. 이를 방지하는 가장 간단한 방법은 Content-Type을 text/plain
귀하의 경우 로 설정하는 것 입니다. application/x-www-form-urlencoded
& multipart/form-data
Content-Types도 허용되지만 물론 요청 페이로드의 형식을 적절하게 지정해야합니다.
이 변경 후에도 여전히 프리 플라이트가 표시되는 경우 Angular가 요청에 X- 헤더를 추가 할 수도 있습니다.
또는 트리거 할 헤더 (Authorization, Cache-Control …)가있을 수 있습니다. 다음을 참조하세요.
답변
Ray가 말했듯이 콘텐츠 헤더를 다음과 같이 수정하여 중지 할 수 있습니다.
$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(){...});
이것은 비행 전 옵션 요청을 보내지 않습니다.
참고 : 요청에는 사용자 지정 헤더 매개 변수가 없어야합니다. 요청 헤더에 사용자 지정 헤더가 포함되어 있으면 브라우저가 사전 요청을 수행하므로 피할 수 없습니다.
답변
특정 유형의 교차 도메인 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”유형인지 확인하여 미들웨어에서 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”. 먼저 크롬의 새 바로 가기를 만들고 속성으로 이동하여 위와 같이 대상을 변경할 수 있습니다. 이것이 도움이 될 것입니다!
답변
content-type을 undefined로 설정하면 javascript가 헤더 데이터를 그대로 전달하고 기본 각도 $ httpProvider 헤더 구성을 덮어 씁니다. Angular $ http 문서
$http({url:url,method:"POST", headers:{'Content-Type':undefined}).then(success,failure);