[angularjs] OPTIONS 프리 플라이트 요청을 건너 뛰는 방법은 무엇입니까?

나는 현재 모바일 웹 사이트로 변환되는 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-dataContent-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);


답변