AngularJS HTTP gönderimi PHP'ye ve tanımsız


107

Etiketli bir formum var ng-submit="login()

Fonksiyon javascript'te fine olarak adlandırılır.

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 dosyasından geri 200 OK yanıtı alıyorum, ancak dönen veriler bunu söylüyor emailve passwordtanımsız. Sahip olduğum tüm php bu

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

Neden tanımsız POSTdeğerler aldığım hakkında bir fikriniz var mı?

DÜZENLE

Bu popüler bir soru gibi göründüğü için (henüz eski) .successve .errorkullanımdan kaldırıldığından ve .then@ James Gentes'in önerilerde belirttiği gibi kullanmanız gerektiğine dikkat çekmek istedim


2
Geliştirici araçlarınızın ağ sekmesine baktınız mı? Hangi değer aktarılır $http?
Marcel Korpel

1
Ağ sekmesinde altındaForm-Data{"email":"fsdg@sdf.com","password":"1234"}
Ronnie

@Ronnie JSON gibi görünüyor. Deneyin print_r($_POST);ve sonra json_decode()doğru dizini deneyin
HamZa

1
echo 'test';iyi çalışıyor. Kesinlikle doğru dosyayı işaret ediyorum
Ronnie

1
.Success ve .error'ın kullanımdan kaldırıldığını ve .then ile değiştirildiğini unutmayın ( docs.angularjs.org/api/ng/service/$http )
James Gentes

Yanıtlar:


228

angularjs .post()varsayılan olarak Content-type başlığını olarak ayarlar application/json. Form kodlu verileri iletmek için bunu geçersiz kılıyorsunuz, ancak datadeğerinizi uygun bir sorgu dizesi geçirecek şekilde değiştirmiyorsunuz , bu nedenle PHP $_POSTbeklediğiniz gibi doldurulmuyor .

Benim önerim application/json, başlık olarak varsayılan angularjs ayarını kullanmak, PHP'deki ham girişi okumak ve ardından JSON'u serileştirmek olacaktır.

Bu, PHP'de şu şekilde başarılabilir:

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

Alternatif olarak, $_POSTişlevselliğe büyük ölçüde güveniyorsanız, buna benzer bir sorgu dizisi oluşturabilir email=someemail@email.com&password=somepasswordve bunu veri olarak gönderebilirsiniz. Bu sorgu dizesinin URL kodlu olduğundan emin olun. Manuel olarak oluşturulmuşsa (gibi bir şey kullanmak yerine jQuery.serialize()), Javascript encodeURIComponent()sizin için hile yapmalıdır.


7
Bilginize saygısızlık etmiyorum, ancak kullanmak bir file_get_contents("php://input");tür hack gibi görünüyor, değil mi? Bunu hiç duymadım. Ne olması gerekiyor ki ona şöyle bir gönderme yapabileyim$_POST['email'];
Ronnie

6
@Ronnie Bu bir hack değil. Bu gerçekten web hizmetinizi nasıl kurmak istediğinize bağlıdır. JSON göndermek ve almak istiyorsanız, $_POSTdoldurulmayacağı için ham girdi ile çalışmanız gerekir .
Mike Brant

1
@lepe Bağlantılı soru / cevabın cevabımla nasıl bir ilişkisi olduğu bana açık değil. Burada bir javascript nesnesini seri hale getirme ihtiyacı tartışılmaz.
Mike Brant

2
@lascort gerçekten çözümlerde pek bir fark yok. Çözümümde, verileri $ _POST içine doldurmuyorum, bunun yerine kullanıcı tanımlı bir değişkeni tercih ediyorum. Genel olarak, JSON ile serileştirilmiş verilerle çalışırken, nesnelerle veya sayısal olarak dizinlenmiş dizilerle çalışıyor olabileceğinizden bu bana daha mantıklı geliyor. Bu alışılmadık bir kullanım olacağı için $ _POST'a sayısal olarak İndisli bir dizi eklemeyi önermem. Ayrıca, girdi verileri için kullanılan süper küresellerin herhangi birine veri koymaktan da genellikle çekiniyorum.
Mike Brant

1
@ItsmeJulian kesin bir doğru cevap yok. Gerçekten uygulamanızın nasıl tasarlandığına bağlı olabilir. JSON tüketen / ileten bir REST hizmetiyle etkileşim halindeyseniz, muhtemelen JSON içerik türüne bağlı kalırım. Büyük ölçüde bir uç nokta ile çalışıyor olsaydım, HTML veya HTML parçaları üretebilir veya AJAX'a geri dönüş olarak temel form gönderimini kullanırsam, o zaman form kodlamasına bağlı kalmaya meyilli olabilirdim.
Mike Brant

41

Bunu sunucu tarafında yapıyorum, init dosyamın başında bir cazibe gibi çalışıyor ve açısal veya mevcut php kodunda hiçbir şey yapmanız gerekmiyor:

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

3
Eğer $ _POST boş durumda sonucunuzu döküm olmalıdır: $_POST = (array) json_decode(file_get_contents('php://input'), true).
M'sieur Toph '

PHP adamlarının bunu neden kendilerinin uygulamadığını gerçekten anlamıyorum, Gerçekten her zaman url kodlu gönderiler bekliyorlar mı ??
azerafati

@Bludream Neden birinin PHP'nin bekleneni yapmasını beklediğini anlamıyorum. Her zaman en az sürpriz ilkesini ihlal ediyor.
doug65536

POST ile gönderilen verilerin ilişkilendirilebilir bir diziyi (JSON'da bir nesne gösterimi) temsil ettiğini kesinlikle bilmediğiniz sürece, bu çok kırılgan bir yaklaşım gibi görünüyor. JSON sayısal olarak indekslenmiş bir dizi gösterimi içeriyorsa ne olur? $_POSTBu durumlarda sayısal olarak indekslenmiş bir dizi elde etmekle sonuçlanır, bu, tutarlı bir $_POSTsüper küresel davranışa dayanan sistemin diğer bölümlerinde çok beklenmedik bir davranış olur.
Mike Brant

1
Elbette bunu sadece açısal güçlendirilmiş uygulamalarda kullanıyorum ve POST verilerimi çok kapsamlı bir şekilde doğruluyorum, bunun nasıl bir sorun olabileceğini görmüyorum ...
valmarv

14

Geliştirdiğim API'de bir temel denetleyicim var ve __construct () yönteminde aşağıdakilere sahibim:

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

Bu, gerektiğinde json verilerine $ _POST ["var"] olarak başvurmama olanak tanır. Harika çalışıyor.

Bu şekilde, kimliği doğrulanmış bir kullanıcı, gönderi verilerini varsayılan Content-Type: application / x-www-form-urlencoded veya Content-Type: application / json ile gönderen bir kitaplığa bağlanırsa, API hatasız yanıt verir ve API'yi biraz daha geliştirici dostu yapın.

Bu yardımcı olur umarım.


11

PHP, JSON'u yerel olarak kabul etmediğinden, 'application/json'bir yaklaşım, api'nizin verileri doğrudan kullanabilmesi için başlıklarınızı ve parametrelerinizi açısaldan güncellemektir.

İlk olarak , verilerinizi parametrelendirin:

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

Ardından aşağıdakileri ekleyin:$http

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

Tüm istekleriniz PHP'ye gidiyorsa, parametreler yapılandırmada aşağıdaki gibi global olarak ayarlanabilir:

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

8

Açısal Js Demo Kodu: -

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

        }]);

Sunucu Yan Kodu: -

<?php


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

?>

Açısal davranış nedeniyle, PHP sunucusunda normal post davranışı için doğrudan bir yöntem yoktur, bu nedenle bunu json nesnelerinde yönetmeniz gerekir.


1
Bu yanlış. JSON'un doğrudan PHP ham girdisinden okunduğu yukarıdaki yanıtlara bakın. Bu, JSON'u sorgu dizesiyle karıştırmaktan çok daha basittir.
Mike Brant

.successVe .erroryöntemler kaldırıldı ve angularjs çerçevesinden çıkarılmıştır.
georgeawg

6

Form verilerinizi ikinci parametre olarak .post () öğesine iletmeden önce serisini kaldırmanız gerekir. Bunu jQuery'nin $ .param (data) yöntemini kullanarak başarabilirsiniz. Daha sonra sunucu tarafında $ .POST ['email'] gibi referans verebileceksiniz;


6

Bu, jQuery ve JSON kod çözme gerektirmediğinden en iyi çözümdür (IMO):

Kaynak: https://wordpress.stackexchange.com/a/179373 ve: https://stackoverflow.com/a/1714899/196507

Özet:

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

Misal:

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

PHP kodu:

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

Peki ya: JSON.stringify('{ id: 'some_id', name : 'some_name' }')ya da $httpParamSerializeristemci tarafı dönüştürme için?
qrtLs

5

Bu eski bir sorudur ancak Angular 1.4 $ httpParamSerializer'ın eklendiğini ve $ http.post kullandığınızda, parametreleri geçirmek için $ httpParamSerializer (params) kullanırsak, her şeyin normal bir post isteği gibi çalıştığını ve JSON serisini kaldırmanın olmadığını belirtmekte fayda var. sunucu tarafında gerekli.

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


1

Angular ve PHP ile çalışırken bunu anlamam saatler aldı. Gönderi verileri $ _POST içinde PHP'ye gitmiyordu

PHP kodunda aşağıdakileri yapın. - Bir değişken $ angular_post_params oluşturun - Sonra aşağıdakileri yapın $angular_http_params = (array)json_decode(trim(file_get_contents('php://input')));

şimdi $ _POST adresinden yaptığınız gibi parametrelerinize erişebilirsiniz

$angular_http_params["key"]

javascript'i merak ediyorsanız ... kullandım bu

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

yeni başlayanlar için ... ng-app ve ng-kontrolör direktifleri :) sayfasında içerik tutucu konteyner ekletmeye unutmak daha dont
Talha

.successVe .erroryöntemler kaldırıldı ve angularjs çerçevesinden çıkarılmıştır.
georgeawg
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.