[javascript] angular.js를 사용하여 HTTP 요청에 사용자 지정 헤더 추가

저는 angular.js의 초보자이며 요청에 헤더를 추가하려고합니다.

   var config = {headers: {
            'Authorization': 'Basic d2VudHdvcnRobWFuOkNoYW5nZV9tZQ==',
            'Accept': 'application/json;odata=verbose'
        }
    };

   $http.get('https://www.example.com/ApplicationData.svc/Malls(1)/Retailers', config).success(successCallback).error(errorCallback);

나는 모든 문서를 보았고 이것이 정확 해야하는 것처럼 보입니다.

에서 URL에 로컬 파일을 사용할 때 $http.getChrome의 네트워크 탭에 다음 HTTP 요청이 표시됩니다.

GET /app/data/offers.json HTTP/1.1
Host: www.example.com
Connection: keep-alive
Cache-Control: max-age=0
If-None-Match: "0f0abc9026855b5938797878a03e6889"
Authorization: Basic Y2hhZHN0b25lbWFuOkNoYW5nZV9tZQ==
Accept: application/json;odata=verbose
X-Requested-With: XMLHttpRequest
If-Modified-Since: Sun, 24 Mar 2013 15:58:55 GMT
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.172 Safari/537.22
X-Testing: Testing
Referer: http://www.example.com/app/index.html
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3

보시다시피 두 헤더가 모두 올바르게 추가되었습니다. 그러나 URL을 $http.get위 의 URL로 변경하면 (example.com이 아닌 실제 주소를 사용하는 경우 제외) 다음과 같은 결과가 나타납니다.

OPTIONS /ApplicationData.svc/Malls(1) HTTP/1.1
Host: www.datahost.net
Connection: keep-alive
Access-Control-Request-Method: GET
Origin: http://mpon.site44.com
User-Agent: Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.172 Safari/537.22
Access-Control-Request-Headers: accept, origin, x-requested-with, authorization, x-testing
Accept: */*
Referer: http://mpon.site44.com/app/index.html
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3

이 두 코드의 유일한 차이점은 첫 번째 URL이 로컬 파일이고 두 번째 URL이 원격 서버라는 것입니다. 두 번째 요청 헤더를 보면 인증 헤더가 없으며 Accept지정된 헤더 대신 기본값을 사용하는 것으로 보입니다. 또한, 첫 번째 줄은 이제 말한다 OPTIONS대신에 GET(비록 Access-Control-Request-Method입니다 GET).

위의 코드에 어떤 문제가 있는지 또는 로컬 파일을 데이터 소스로 사용하지 않을 때 사용하여 추가 헤더를 얻는 방법을 알고 있습니까?



답변

나는 당신이 가진 것을 가져다가 다른 X-Testing헤더를 추가했습니다.

var config = {headers:  {
        'Authorization': 'Basic d2VudHdvcnRobWFuOkNoYW5nZV9tZQ==',
        'Accept': 'application/json;odata=verbose',
        "X-Testing" : "testing"
    }
};

$http.get("/test", config);

Chrome 네트워크 탭에서 전송되는 것을 봅니다.

GET /test HTTP/1.1
Host: localhost:3000
Connection: keep-alive
Accept: application/json;odata=verbose
X-Requested-With: XMLHttpRequest
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_3) AppleWebKit/537.22 (KHTML, like Gecko) Chrome/25.0.1364.172 Safari/537.22
Authorization: Basic d2VudHdvcnRobWFuOkNoYW5nZV9tZQ==
X-Testing: testing
Referer: http://localhost:3000/
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3

브라우저 나 서버에서 볼 수 없습니까? 브라우저 도구 또는 디버그 프록시를 사용해보고 무엇이 전송되는지 확인하십시오.


답변

HTTP POST 방법을 사용한 기본 인증 :

$http({
    method: 'POST',
    url: '/API/authenticate',
    data: 'username=' + username + '&password=' + password + '&email=' + email,
    headers: {
        "Content-Type": "application/x-www-form-urlencoded",
        "X-Login-Ajax-call": 'true'
    }
}).then(function(response) {
    if (response.data == 'ok') {
        // success
    } else {
        // failed
    }
});

… 헤더가있는 GET 메서드 호출 :

$http({
    method: 'GET',
    url: '/books',
    headers: {
        'Authorization': 'Basic d2VudHdvcnRobWFuOkNoYW5nZV9tZQ==',
        'Accept': 'application/json',
        "X-Login-Ajax-call": 'true'
    }
}).then(function(response) {
    if (response.data == 'ok') {
        // success
    } else {
        // failed
    }
});


답변

모든 요청에 ​​사용자 정의 헤더를 추가하려면 $ httpProvider의 기본값을 변경하여 항상이 헤더를 추가 할 수 있습니다.

app.config(['$httpProvider', function ($httpProvider) {
    $httpProvider.defaults.headers.common = {
        'Authorization': 'Basic d2VudHdvcnRobWFuOkNoYW5nZV9tZQ==',
        'Accept': 'application/json;odata=verbose'
      };
}]);


답변

내 제안은 함수 내부에 이와 같은 함수 호출 설정을 추가하여 적절한 헤더를 확인하는 것입니다. 나는 그것이 확실히 작동 할 것이라고 확신합니다. 그것은 나를 위해 완벽하게 작동합니다.

function getSettings(requestData) {
    return {
        url: requestData.url,
        dataType: requestData.dataType || "json",
        data: requestData.data || {},
        headers: requestData.headers || {
            "accept": "application/json; charset=utf-8",
            'Authorization': 'Bearer ' + requestData.token
        },
        async: requestData.async || "false",
        cache: requestData.cache || "false",
        success: requestData.success || {},
        error: requestData.error || {},
        complete: requestData.complete || {},
        fail: requestData.fail || {}
    };
}

다음과 같이 데이터를 호출하십시오.

    var requestData = {
        url: 'API end point',
        data: Your Request Data,
        token: Your Token
    };

    var settings = getSettings(requestData);
    settings.method = "POST"; //("Your request type")
    return $http(settings);


답변

OPTIONS 요청에 대해 표시되는 내용은 괜찮습니다. 권한 헤더는 여기에 표시되지 않습니다.

그러나 기본 인증이 작동하려면 다음을 추가해야 withCredentials = true;합니다.var config .

AngularJS $ http 문서에서 :

withCredentials
XHR 객체에 플래그 {boolean}를 설정할지 여부 withCredentials. 자세한 내용 은 자격 증명이있는 요청 을 참조하세요.


답변

그리고 서버의 답은 무엇입니까? 204에 응답 한 다음 실제로 요청하는 GET을 보내야합니다.

OPTIONS에서 클라이언트는 서버가 CORS 요청을 허용하는지 확인합니다. 204와 다른 것을 제공하는 경우 올바른 Allow-Origin 헤더를 보내도록 서버를 구성해야합니다.

헤더를 추가하는 방법이 올바른 방법입니다.


답변

Chrome은 CORS 헤더를 찾는 요청을 프리 플라이트하고 있습니다. 요청이 허용되면 실제 요청을 보냅니다. 이 교차 도메인을 수행하는 경우 단순히 처리하거나 요청을 비 교차 도메인으로 만드는 방법을 찾아야합니다. 이것은 의도적으로 설계된 것입니다.

간단한 요청 (위에서 설명 함)과 달리 “프리 플라이트 된”요청은 실제 요청을 보내는 것이 안전한지 여부를 확인하기 위해 먼저 OPTIONS 메서드에 의해 다른 도메인의 리소스에 HTTP 요청을 보냅니다. 교차 사이트 요청은 사용자 데이터에 영향을 미칠 수 있으므로 이와 같이 미리 실행됩니다. 특히 다음과 같은 경우 요청이 프리 플라이트됩니다.

GET, HEAD 또는 POST 이외의 방법을 사용합니다. 또한 POST가 application / x-www-form-urlencoded, multipart / form-data 또는 text / plain 이외의 Content-Type으로 요청 데이터를 보내는 데 사용되는 경우 (예 : POST 요청이 XML 페이로드를 서버로 보내는 경우) application / xml 또는 text / xml을 사용하면 요청이 프리 플라이트됩니다. 요청에 사용자 정의 헤더를 설정합니다 (예 : 요청이 X-PINGOTHER와 같은 헤더를 사용함).

참고 : Chrome의 AJAX가 GET / POST / PUT / DELETE 대신 옵션을 전송합니까?