PHP에 AngularJS HTTP 게시 및 정의되지 않음


107

태그가있는 양식이 있습니다. ng-submit="login()

이 함수는 자바 스크립트에서 잘 호출됩니다.

function LoginForm($scope, $http)
{
    $http.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8';

    $scope.email    = "fsdg@sdf.com";
    $scope.password = "1234";

    $scope.login = function()
    {
        data = {
            'email' : $scope.email,
            'password' : $scope.password
        };

        $http.post('resources/curl.php', data)
        .success(function(data, status, headers, config)
        {
            console.log(status + ' - ' + data);
        })
        .error(function(data, status, headers, config)
        {
            console.log('error');
        });
    }
}

나는 PHP 파일에서 200 OK 응답 등을 얻고있다, 그러나, 반환 된 데이터는 것을 말하고 emailpassword정의되지 않은 있습니다. 이것은 내가 가진 모든 PHP입니다

<?php
$email = $_POST['email'];
$pass  = $_POST['password'];
echo $email;
?>

왜 내가 정의되지 않은 POST값을 얻는 지 아십니까?

편집하다

나는이 (아직 나이입니다) 인기 질문 것으로 보인다 이후 지적하고 싶었, .success그리고 .error사용되지 않으며 당신은 사용해야 .then@ 제임스 씨족이 commments에서 지적


2
개발자 도구의 네트워크 탭을 보셨습니까? 어떤 값이 전달 $http됩니까?
Marcel Korpel 2013 년

1
네트워크 탭에서 아래에 Form-Data그것을 말한다{"email":"fsdg@sdf.com","password":"1234"}
로니

@Ronnie는 JSON처럼 보입니다. 시도 print_r($_POST);하고 시도 json_decode()올바른 인덱스
함자

1
echo 'test';잘 작동합니다. 난 분명 올바른 파일을 가리키는입니다
로니

1
.success 및 .error는 더 이상 사용되지 않고 .then ( docs.angularjs.org/api/ng/service/$http )으로 대체되었습니다.
James Gentes

답변:


228

angularjs는 .post()기본적으로 Content-type 헤더를 application/json. 양식으로 인코딩 된 데이터를 전달하기 위해 이것을 재정의하고 있지만 data적절한 쿼리 문자열을 전달하도록 값을 변경하지 않으므로 PHP가 $_POST예상대로 채워지지 않습니다 .

내 제안은 기본 angularjs 설정을 application/json헤더로 사용하고 PHP에서 원시 입력을 읽은 다음 JSON을 역 직렬화하는 것입니다.

다음과 같이 PHP에서 수행 할 수 있습니다.

$postdata = file_get_contents("php://input");
$request = json_decode($postdata);
$email = $request->email;
$pass = $request->password;

또는 $_POST기능에 크게 의존하는 경우 다음 과 같은 쿼리 문자열 email=someemail@email.com&password=somepassword을 구성하여 데이터로 보낼 수 있습니다. 이 쿼리 문자열이 URL로 인코딩되었는지 확인하십시오. 수동으로 빌드하는 경우 (같은 것을 사용하는 것과는 반대로 jQuery.serialize()) Javascript가 encodeURIComponent()트릭을 수행해야합니다.


7
당신의 지식을 무시하지는 않지만 사용하는 file_get_contents("php://input");것은 일종의 해킹처럼 보입니다. 나는 이것을 들어 본 적이 없다. 어떻게 내가처럼 참조 할 수 있도록 일이 필요$_POST['email'];
로니

6
@Ronnie 그것은 해킹이 아닙니다. 실제로 웹 서비스를 설정하려는 방법에 따라 다릅니다. JSON을 보내고 검색하려면 $_POST채워지지 않으므로 원시 입력으로 작업해야합니다 .
Mike Brant

1
@lepe 연결된 질문 / 답변이 내 답변과 어떤 관련이 있는지 명확하지 않습니다. 여기에서는 자바 스크립트 객체를 직렬화해야한다는 논의가 없습니다.
Mike Brant 2015 년

2
@lascort는 실제로 솔루션에 큰 차이가 없습니다. 내 솔루션에서는 데이터를 $ _POST에 채우지 않고 대신 사용자 정의 변수를 선호합니다. 일반적으로 JSON 직렬화 된 데이터로 작업 할 때 객체 또는 숫자 색인 배열로 작업 할 수 있다는 점에서이 방법이 더 합리적입니다. $ _POST에 숫자 인덱스 배열을 추가하는 것은 비정형적인 용도이므로 권장하지 않습니다. 또한 일반적으로 입력 데이터에 사용되는 수퍼 글로벌에 데이터를 넣는 것을 피합니다.
마이크 브랜트

1
@ItsmeJulian 절대 정답이 없습니다. 실제로 애플리케이션이 어떻게 설계되었는지에 따라 달라질 수 있습니다. JSON을 소비 / 제공하는 REST 서비스와 상호 작용하는 경우 아마도 JSON 콘텐츠 유형을 고수 할 것입니다. 주로 엔드 포인트를 사용하여 HTML 또는 HTML 조각을 생성하거나 기본 양식 게시를 AJAX에 대한 폴백으로 사용할 수 있다면 양식 인코딩을 고수하는 경향이 있습니다.
Mike Brant

41

init 파일의 시작 부분에서 서버 측에서 수행하며 매력처럼 작동하며 각도 또는 기존 PHP 코드에서 아무것도 할 필요가 없습니다.

if ($_SERVER['REQUEST_METHOD'] == 'POST' && empty($_POST))
    $_POST = json_decode(file_get_contents('php://input'), true);

3
$ _POST가 비어있는 경우 결과를 캐스팅해야합니다 $_POST = (array) json_decode(file_get_contents('php://input'), true).
M'sieur Toph '2014 년

나는 왜 PHP 사람들이 이것을 스스로 구현하지 않았는지 알지 못합니다. 그들은 항상 URL 인코딩 게시물을 기대합니까 ??
azerafati

@Bludream 나는 PHP가 기대하는 것을 왜 기대하는지 이해하지 못한다. 그것은 항상 최소한의 놀라움의 원칙을 위반합니다.
doug65536

POST 된 데이터가 연관 배열 (JSON의 객체 표현)을 나타내지 않는 한 이것은 매우 취약한 접근 방식처럼 보입니다. JSON에 숫자 색인 배열 표현이 포함되어 있다면 어떻게됩니까? $_POST이 경우 숫자 인덱스 배열을 얻게됩니다. 이는 일관된 $_POST슈퍼 글로벌 동작에 의존하는 시스템의 다른 부분에서 매우 예상치 못한 동작입니다 .
Mike Brant 2015 년

1
... 나는 단지 물론, 각 전원 애플리케이션에서 이것을 사용하고, 나는이 문제가 될 수있는 방법을 볼 수 없습니다, 아주 철저하게 내 POST 데이터의 유효성을 검사
valmarv

14

API에서 개발 중이며 기본 컨트롤러가 있고 __construct () 메서드 내부에 다음이 있습니다.

if(isset($_SERVER["CONTENT_TYPE"]) && strpos($_SERVER["CONTENT_TYPE"], "application/json") !== false) {
    $_POST = array_merge($_POST, (array) json_decode(trim(file_get_contents('php://input')), true));
}

이렇게하면 필요할 때 json 데이터를 $ _POST [ "var"]로 간단히 참조 할 수 있습니다. 잘 작동합니다.

이렇게하면 인증 된 사용자가 기본 Content-Type : application / x-www-form-urlencoded 또는 Content-Type : application / json을 사용하여 게시 데이터를 보내는 jQuery와 같은 라이브러리에 연결하면 API가 오류없이 응답하고 API를 좀 더 개발자 친화적으로 만듭니다.

도움이 되었기를 바랍니다.


11

PHP는 기본적으로 JSON을 허용하지 않기 때문에 'application/json'API가 데이터를 직접 사용할 수 있도록 앵귤러에서 헤더와 매개 변수를 업데이트하는 것입니다.

먼저 데이터를 매개 변수화합니다.

data: $.param({ "foo": $scope.fooValue })

그런 다음 다음을 귀하의$http

 headers: {
     'Content-Type' : 'application/x-www-form-urlencoded; charset=UTF-8'
 }, 

모든 요청이 PHP로 이동하는 경우 다음과 같이 구성에서 매개 변수를 전역으로 설정할 수 있습니다.

myApp.config(function($httpProvider) {
    $httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8';
});

8

Angular Js 데모 코드 :-

angular.module('ModuleName',[]).controller('main', ['$http', function($http){

                var formData = { password: 'test pwd', email : 'test email' };
                var postData = 'myData='+JSON.stringify(formData);
                $http({
                        method : 'POST',
                        url : 'resources/curl.php',
                        data: postData,
                        headers : {'Content-Type': 'application/x-www-form-urlencoded'}  

                }).success(function(res){
                        console.log(res);
                }).error(function(error){
                        console.log(error);
        });

        }]);

서버 측 코드 :-

<?php


// it will print whole json string, which you access after json_decocde in php
$myData = json_decode($_POST['myData']);
print_r($myData);

?>

각도 동작으로 인해 PHP 서버에서 일반적인 포스트 동작에 대한 직접적인 방법이 없으므로 json 객체에서 관리해야합니다.


1
이것은 올바르지 않습니다. JSON이 PHP 원시 입력에서 직접 읽히는 위의 답변을 참조하십시오. 이것은 JSON을 쿼리 문자열에 혼합하는 것보다 훨씬 간단합니다.
마이크 브랜트

.success.error방법은 사용되지 않습니다와 AngularJS와 프레임 워크에서 제거되었습니다.
georgeawg

6

.post ()에 두 번째 매개 변수로 전달하기 전에 양식 데이터를 역 직렬화해야합니다. jQuery의 $ .param (데이터) 메서드를 사용하여이를 수행 할 수 있습니다. 그러면 서버 측에서 $ .POST [ 'email']과 같이 참조 할 수 있습니다.


6

이것은 jQuery와 JSON 디코딩이 필요하지 않기 때문에 최상의 솔루션 (IMO)입니다.

출처 : https://wordpress.stackexchange.com/a/179373 및 : https://stackoverflow.com/a/1714899/196507

요약:

//Replacement of jQuery.param
var serialize = function(obj, prefix) {
  var str = [];
  for(var p in obj) {
    if (obj.hasOwnProperty(p)) {
      var k = prefix ? prefix + "[" + p + "]" : p, v = obj[p];
      str.push(typeof v == "object" ?
        serialize(v, k) :
        encodeURIComponent(k) + "=" + encodeURIComponent(v));
    }
  }
  return str.join("&");
};

//Your AngularJS application:
var app = angular.module('foo', []);

app.config(function ($httpProvider) {
    // send all requests payload as query string
    $httpProvider.defaults.transformRequest = function(data){
        if (data === undefined) {
            return data;
        }
        return serialize(data);
    };

    // set all post requests content type
    $httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8';
});

예:

...
   var data = { id: 'some_id', name : 'some_name' };
   $http.post(my_php_url,data).success(function(data){
        // It works!
   }).error(function() {
        // :(
   });

PHP 코드 :

<?php
    $id = $_POST["id"];
?>

무엇에 대해 : JSON.stringify('{ id: 'some_id', name : 'some_name' }')또는 $httpParamSerializer클라이언트 측 변환을위한?
qrtLs

5

오래된 질문이지만 Angular 1.4에서 $ httpParamSerializer가 추가되고 $ http.post를 사용할 때 $ httpParamSerializer (params)를 사용하여 매개 변수를 전달하면 모든 것이 일반 게시 요청처럼 작동하며 JSON 역 직렬화가 없음을 언급 할 가치가 있습니다. 서버 측에 필요합니다.

https://docs.angularjs.org/api/ng/service/$httpParamSerializer


1

Angular와 PHP로 작업하는 동안 이해하는 데 몇 시간이 걸렸습니다. $ _POST의 게시물 데이터가 PHP로 전송되지 않았습니다.

PHP 코드에서 다음을 수행하십시오. -$ angular_post_params 변수 만들기-그런 다음 다음을 수행합니다. $angular_http_params = (array)json_decode(trim(file_get_contents('php://input')));

이제 $ _POST 에서처럼 매개 변수에 액세스 할 수 있습니다.

$angular_http_params["key"]

당신이 자바 스크립트에 대해 궁금한 경우 .... 이것은 내가 사용한 것입니다

    var myApp = angular.module('appUsers', []);
    //var post_params = $.param({ request_type: "getListOfUsersWithRolesInfo" });
    var dataObj = {
        task_to_perform: 'getListOfUsersWithRolesInfo'
    };

    myApp.controller('ctrlListOfUsers', function ($scope, $http) {
        $http({
            method: 'POST',
            dataType: 'json',
            url: ajax_processor_url,
            headers: {
                'Content-Type': 'application/json'
            },
            data: dataObj,
            //transformRequest: function(){},
            timeout: 30000,
            cache: false
        }).
        success(function (rsp) {
            console.log("success");
            console.log(rsp);
        }).
        error(function (rsp) {
            console.log("error");
        });
    });

초보자를 위해 ... 페이지의 콘텐츠 홀더 컨테이너에 ng-app 및 ng-controller 지시문을 추가하는 것을 잊지 마십시오. :)
Talha

.success.error방법은 사용되지 않습니다와 AngularJS와 프레임 워크에서 제거되었습니다.
georgeawg
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.