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


89

저는 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).

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


2
이것은 CORS 문제처럼 보입니다. 몇 가지 배경에 대해이 토론을 읽어보십시오. groups.google.com/forum/#!topic/angular/CSBMY6oXfqs
Kevin Hakanson 2013 년

실제로 CORS 문제였습니다. 서버가 Access-Control-Allow-Origin : 헤더를 반환하도록 구성되지 않았습니다. 귀하의 의견과 CORS에 대한 약간의 세부 사항과 함께 답변을 작성하고 싶다면 귀하의 답변을 수락하겠습니다. Dmitry Evseev의 아래 답변은 귀하가 편집했지만 실제 문제는 아닙니다.
trentclowater

1
Chrome은 요청이 교차 도메인 인 경우 CORS 헤더를 찾기 위해 요청을 프리 플라이트합니다. 내 대답을 확인하십시오.
Asim KT

답변:


66

나는 당신이 가진 것을 가져다가 다른 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

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


서버에 액세스 할 수없고 브라우저에서 Firefox를 사용하고 있지만 위의 원래 질문에 추가 한 헤더가 표시됩니다. Chrome의 리소스 탭에서 헤더를 볼 수있는 위치를 찾을 수 없습니다.
trentclowater 2013 년

죄송합니다. 원래 질문에 포함되도록 답변을 수정했습니다.
trentclowater 2013 년

리소스가 아닌 개발자 도구의 네트워크 탭을 의미했습니다. 업데이트 답변
Kevin Hakanson 2013 년

질문에 더 많은 정보를 추가했습니다. 헤더가 한 경우에 추가되었지만 다른 경우에는 추가되지 않은 것 같습니다.
trentclowater 2013 년

21

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
    }
});

최고의 답변입니다.
Yoda

9

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

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

OPTIONS 요청을 제외한 모든 요청
Rocco

좋은 예. 페이지 리디렉션을 위해 토큰을 캐시하는 데 사용할 수 있습니까?
Martian2049

7

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

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);

2

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

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

AngularJS $ http 문서에서 :

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


1

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

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

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


1

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 대신 옵션을 전송합니까?


-8

나를 위해 다음 설명 스 니펫이 작동했습니다. '헤더 이름에 사용하지 말아야 할까요?

{
   headers: { 
      Authorization: "Basic " + getAuthDigest(), 
      Accept: "text/plain" 
   }
}

나는 그것이 $http.ajax()게임 체인저가 될 것이라고 기대하지는 않지만를 사용 하고 있습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.