AngularJS-$ http.post가 JSON 대신 요청 매개 변수를 보내는 방법은 없나요?


116

jQuery의 post 메서드를 통해 AJAX POST 요청을 만드는 오래된 코드가 있으며 다음과 같습니다.

$.post("/foo/bar", requestData,
    function(responseData)
    {
        //do stuff with response
    }

requestData 기본적인 문자열 속성이있는 자바 스크립트 객체 일뿐입니다.

저는 Angular를 사용하기 위해 우리의 물건을 옮기는 과정에 있으며,이 호출을 $ http.post로 바꾸고 싶습니다. 나는 다음을 생각 해냈다.

$http.post("/foo/bar", requestData).success(
    function(responseData) {
        //do stuff with response
    }
});

이 작업을 수행했을 때 서버에서 500 오류 응답을 받았습니다. Firebug를 사용하여 다음과 같은 요청 본문을 보냈습니다.

{"param1":"value1","param2":"value2","param3":"value3"}

성공적인 jQuery $.post는 다음과 같이 본문을 보냅니다.

param1=value1&param2=value2&param3=value3

내가 치는 엔드 포인트는 JSON이 아닌 요청 매개 변수를 예상하고 있습니다. 그래서, 내 질문은 어쨌든 $http.postJSON 대신 요청 매개 변수로 자바 스크립트 개체를 보내 라고 말할 수 있습니까? 예, 객체에서 직접 문자열을 구성 할 수 있다는 것을 알고 있지만 Angular가이를 위해 즉시 사용할 수있는 것이 있는지 알고 싶습니다.

답변:


140

params구성 매개 변수가 본문 대신 URL에 문자열을 추가하기 때문에 여기에서 작동하지 않을 것이라고 생각 하지만 여기에서 Infeligo가 제안한 내용을 추가하는 것은 기본 변환의 전역 재정의 예제입니다 (jQuery 매개 변수 를 변환하는 예제로 사용). 매개 변수 문자열에 대한 데이터).

전역 transformRequest 함수를 설정합니다.

var app = angular.module('myApp');

app.config(function ($httpProvider) {
    $httpProvider.defaults.transformRequest = function(data){
        if (data === undefined) {
            return data;
        }
        return $.param(data);
    }
});

이렇게하면 $ http.post에 대한 모든 호출이 자동으로 본문을 jQuery $.post호출에서 사용하는 것과 동일한 매개 변수 형식으로 변환합니다 .

호출 당 또는 다음과 같이 전역 적으로 Content-Type 헤더를 설정할 수도 있습니다.

$httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8';

호출 당 샘플 비전 역 transformRequest :

    var transform = function(data){
        return $.param(data);
    }

    $http.post("/foo/bar", requestData, {
        headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'},
        transformRequest: transform
    }).success(function(responseData) {
        //do stuff with response
    });

transformRequest 함수 외에 다른 것이 있는지 궁금했지만없는 것 같습니다. jQuery param 함수에 대해 알려 주셔서 감사합니다.
dnc253

Non-global per call method는 저에게 잘 작동하지만을 통해 전역 적으로 설정하려고 할 때 $httpProvider.defaults작동하지 않습니다. 이에 대한 단서가 있습니까?
Dfr

1
WRT가 전 세계적으로 구성하는데도 문제가 있습니다. 여기에 제공된 스 니펫을 사용하여 시도 할 때 오류가 발생합니다. Cannot read property "jquery" of undefined.어떻게 수정합니까? 추신. 통화 당 변환이 작동합니다.
kshep92

@ kshep92 무슨 일이 일어나고 있는지는 데이터가없는 요청에서 transformRequest 함수가 호출되어 '데이터'가 정의되지 않은 것입니다. 'return $ .param (data);'전에 가드를 추가했습니다. transformRequest 함수의 첫 번째 줄로 삽입합니다. 'if (data === undefined) return data;' 대답에 대한 편집을 참조하십시오.
Jere.Jones 2013-02-05


21

Angular> = 1.4를 사용하는 경우 사용자 지정 또는 외부에 의존하지 않는 가장 깨끗한 솔루션은 다음과 같습니다.

angular.module('yourModule')
  .config(function ($httpProvider, $httpParamSerializerJQLikeProvider){
    $httpProvider.defaults.transformRequest.unshift($httpParamSerializerJQLikeProvider.$get());
    $httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded; charset=utf-8';
});

그런 다음 앱 어디에서나이 작업을 수행 할 수 있습니다.

$http({
  method: 'POST',
  url: '/requesturl',
  data: {
    param1: 'value1',
    param2: 'value2'
  }
});

그리고 엔드 포인트에 대한 POST 요청에서 일반적으로 예상되는대로 데이터를 올바르게 직렬화하고 Content-Type 헤더 와 함께 param1=value1&param2=value2전송 합니다./requesturlapplication/x-www-form-urlencoded; charset=utf-8


17

AngularJS 문서에서 :

params – {Object.} – URL 뒤에? key1 = value1 & key2 = value2로 바뀔 문자열 또는 개체의 맵입니다. 값이 문자열이 아닌 경우 JSON으로 처리됩니다.

따라서 문자열을 매개 변수로 제공하십시오. 원하지 않으면 변환을 사용하십시오. 다시 말하지만, 문서에서 :

이러한 변환을 로컬로 재정의하려면 변환 함수를 config 개체의 transformRequest 및 / 또는 transformResponse 속성으로 지정합니다. 기본 변환을 전역 적으로 재정의하려면 $ httpProvider의 $ httpProvider.defaults.transformRequest 및 $ httpProvider.defaults.transformResponse 속성을 재정의합니다.

자세한 내용은 설명서 를 참조하십시오.


설명서에서 매개 변수를 보았고 Gloopy가 언급했듯이 URL이 아닌 본문에 필요합니다. JSON 대신 매개 변수를 수행하기 위해 누락 된 옵션이나 무언가가 있는지 궁금했지만 transformRequest 속성을 사용해야하는 것 같습니다.
dnc253

15

jQuery의 $.param함수를 사용 하여 requestData에서 JSON 데이터를 직렬화합니다.

요컨대, 유사한 코드를 사용하십시오.

$http.post("/foo/bar",
$.param(requestData),
{
    headers:
    {
        'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
    }
}
).success(
    function(responseData) {
        //do stuff with response
    }
});

이를 사용하려면 AngularJS와 함께 페이지에 jQuery를 포함해야합니다.


7

Angular 1.4부터는 jQuery를 사용하지 않고도 양식 데이터를 직렬화 할 수 있습니다.

app.js에서 :

module.run(function($http, $httpParamSerializerJQLike) {
  $http.defaults.transformRequest.unshift($httpParamSerializerJQLike);
});

그런 다음 컨트롤러에서 :

$http({
    method: 'POST',
    url: myUrl',
    headers: {'Content-Type': 'application/x-www-form-urlencoded'},
    data: myData
});

이 대답은 훌륭합니다. Angular의 Post의 두 가지 주요 문제를 해결합니다. 헤더를 올바르게 설정하고 json 데이터를 직렬화해야합니다. IE8 지원이 필요하지 않은 경우 1.4 이상을 사용하십시오.
mbokil

방금 이것을 구현하고 게시물과 관련된 문제를 해결했지만 이것은 패치 작동 방식을 변경하고 $ http.patch ()의 모든 사용을 망친 것처럼 보입니다.
Mike

5

이것은 약간의 해킹 일 수 있지만 문제를 피하고 json을 서버 측에서 PHP의 POST 배열로 변환했습니다.

$_POST = json_decode(file_get_contents('php://input'), true);

나는이 방법을 사용했지만 나는 그것을 싫어한다. 왜 이것을 사용해야하는지 알아내는 데 오랜 시간이 걸렸습니다.
meconroy

내가 말했듯이-해키 느낌. PHP의처럼 대부분)
TimoSolo

5

$ resource가 요청을 캐시하기 때문에 사용자 지정 http 인증을 설정하는 데 문제가 있습니다.

작동하게하려면이 작업을 수행하여 기존 헤더를 덮어 써야합니다.

var transformRequest = function(data, headersGetter){
  var headers = headersGetter();
  headers['Authorization'] = 'WSSE profile="UsernameToken"';
  headers['X-WSSE'] = 'UsernameToken ' + nonce
  headers['Content-Type'] = 'application/json';
};

return $resource(
  url,
    {
    },
    {
      query: {
        method: 'POST',
        url: apiURL + '/profile',
        transformRequest: transformRequest,
        params: {userId: '@userId'}
      },
    }
);

누군가를 도울 수 있었기를 바랍니다. 이걸 알아내는 데 3 일이 걸렸습니다.


방금 3 일의 작업을 구해준 것 같습니다. 감사!!! 나는 모든 호출에 대해 사용자 정의 헤더를 삽입 할 수 있도록 어떻게 든 요청 호출을 가로 챌 수 있는지 알아 내려고 노력하고 있습니다.
marcoseu

4

기본 헤더를 수정합니다.

$http.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded;charset=utf-8";

그런 다음 JQuery의 $.param방법을 사용하십시오.

var payload = $.param({key: value});
$http.post(targetURL, payload);

3
   .controller('pieChartController', ['$scope', '$http', '$httpParamSerializerJQLike', function($scope, $http, $httpParamSerializerJQLike) {
        var data = {
                TimeStamp : "2016-04-25 12:50:00"
        };
        $http({
            method: 'POST',
            url: 'serverutilizationreport',
            headers: {'Content-Type': 'application/x-www-form-urlencoded'},
            data: $httpParamSerializerJQLike(data),
        }).success(function () {});
    }
  ]);

나에 따르면 가장 간단하고 쉬운 방법 ... 다른 많은 방법이있을 수 있습니다
Rohit Luthra

2

빠른 조정-transformRequest 함수의 전역 구성에 문제가있는 사용자를 위해 다음은 Cannot read property 'jquery' of undefined오류를 제거하는 데 사용하는 스 니펫입니다 .

$httpProvider.defaults.transformRequest = function(data) {
        return data != undefined ? $.param(data) : null;
    }


0

나는이 전체의 문제가되는 행동을 여러 번 발견했다. 나는 그것을 express (타이핑없이)와 bodyParser (dt ~ body-parser 타이핑과 함께)에서 사용했다.

나는 파일을 업로드하지 않고 단순히 포스트 문자열에 주어진 JSON을 해석하려고했습니다.

(가) request.body단순히 빈 JSON이었다 ( {}).

많은 조사 끝에 마침내 이것은 나를 위해 일했습니다.

import { json } from 'body-parser';
...
app.use(json()); <-- should be defined before the first POST handler!

application/json클라이언트 측의 요청 문자열에 콘텐츠 유형 을 제공하는 것도 중요 할 수 있습니다 .


불행히도 타이프 스크립트 / 노드 / 앵글 환경의 현재 단계에서 흔히 볼 수있는 "검은 암탉을 희생한다"스타일의 대답에 대해 유감입니다.
peterh-Monica 복원

0

AngularJS v1.4.8 + (v1.5.0) 구문

       $http.post(url, data, config)
            .then(
                    function (response) {
                        // success callback
                    },
                    function (response) {
                        // failure callback
                    }
            );

예 :

    var url = "http://example.com";

    var data = {
        "param1": "value1",
        "param2": "value2",
        "param3": "value3"
    };

    var config = {
        headers: {
            'Content-Type': "application/json"
        }
    };

    $http.post(url, data, config)
            .then(
                    function (response) {
                        // success callback
                    },
                    function (response) {
                        // failure callback
                    }
            );
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.