AngularJs $ http.post () veri göndermiyor


337

Birisi bana aşağıdaki ifadenin neden yazı verilerini belirtilen url'ye göndermediğini söyleyebilir mi? Url denir ama $ _POST yazdırdığımda sunucuda - Boş bir dizi olsun. Verilere eklemeden önce konsola mesaj yazdırırsam doğru içeriği gösterir.

$http.post('request-url',  { 'message' : message });

Ben de (aynı sonuç ile) dize gibi verilerle denedim:

$http.post('request-url',  "message=" + message);

Aşağıdaki biçimde kullandığımda çalışıyor gibi görünüyor:

$http({
    method: 'POST',
    url: 'request-url',
    data: "message=" + message,
    headers: {'Content-Type': 'application/x-www-form-urlencoded'}
});

ancak bunu $ http.post () ile yapmanın bir yolu var mı? Çalışması için her zaman üstbilgiyi eklemem gerekir mi? Yukarıdaki içerik türünün gönderilen verilerin biçimini belirlediğine inanıyorum, ancak javascript nesnesi olarak gönderebilir miyim?


URL aynı kökente mi?
fmquaglia

Üzgünüz - evet tüm örnekler için aynı url
Spencer Mark

@ SpencerMark üzgünüm .. çalışma kodunuzun üzerinde denedim .. bu benim için çalışmıyor.
Arul Sidthan

Yanıtlar:


346

Aynı sorunu asp.net MVC kullanarak yaşadım ve çözümü burada buldum

AngularJS'ye yeni gelenler arasında , $httphizmet kısayol işlevlerinin ( $http.post()vb.) JQuery eşdeğerleriyle ( jQuery.post(), vb.)

Aradaki fark, jQuery ve AngularJS'nin verileri serileştirme ve iletme şeklindedir. Temel olarak, sorun seçtiğiniz sunucu dilinin AngularJS'nin iletimini doğal olarak anlayamamasıdır ... Varsayılan olarak, jQuery verileri kullanarak iletir

Content-Type: x-www-form-urlencoded

ve tanıdık foo=bar&baz=moeseri hale getirme.

Ancak AngularJS , verileri kullanarak

Content-Type: application/json 

ve { "foo": "bar", "baz": "moe" }

Ne yazık ki bazı Web sunucusu dillerinin ( özellikle PHP) yerel olarak serileştirilmediği JSON serileştirmesi .

Tıkır tıkır çalışıyor.

KOD

// Your app's root module...
angular.module('MyModule', [], function($httpProvider) {
  // Use x-www-form-urlencoded Content-Type
  $httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8';

  /**
   * The workhorse; converts an object to x-www-form-urlencoded serialization.
   * @param {Object} obj
   * @return {String}
   */ 
  var param = function(obj) {
    var query = '', name, value, fullSubName, subName, subValue, innerObj, i;

    for(name in obj) {
      value = obj[name];

      if(value instanceof Array) {
        for(i=0; i<value.length; ++i) {
          subValue = value[i];
          fullSubName = name + '[' + i + ']';
          innerObj = {};
          innerObj[fullSubName] = subValue;
          query += param(innerObj) + '&';
        }
      }
      else if(value instanceof Object) {
        for(subName in value) {
          subValue = value[subName];
          fullSubName = name + '[' + subName + ']';
          innerObj = {};
          innerObj[fullSubName] = subValue;
          query += param(innerObj) + '&';
        }
      }
      else if(value !== undefined && value !== null)
        query += encodeURIComponent(name) + '=' + encodeURIComponent(value) + '&';
    }

    return query.length ? query.substr(0, query.length - 1) : query;
  };

  // Override $http service's default transformRequest
  $httpProvider.defaults.transformRequest = [function(data) {
    return angular.isObject(data) && String(data) !== '[object File]' ? param(data) : data;
  }];
});

7
Ben bu komut dosyası bower ekledim, bower install angular-post-fix --save-deveklemek için kullanın .
Billy Blaze

Bu yüzden php iletir veri yöntemini değiştirmek için bir yolu var. Çünkü şu an yaşadığım sorun bu.
22'de Demodave

1
Bu kod çoğunlukla harika çalışıyor, ancak boş nesneler veya hatta düz boş değerler hiyerarşisi gönderirken sorun yaşadım. Örneğin, {a: 1, b: {c: {d: {}}}, e: tanımsız, f: null, g: 2} düzgün kodlanmayacak ve PHP bunu ["a" = olarak alacak > "1", "g" => "2"]. "B" altındaki tüm yapı ve anahtarlar da dahil olmak üzere "e" ve "f" nin tümü kaybolacaktır. Yukarıdaki yapının şu şekilde kodu çözüldüğü alternatif bir kod yayınladım: ["a" => "1", "b" => ["c" => ["d" => ""]], "e" => "", "f" => "", "g" => "2"].
obe

1
bunu çok parçalı / form verileri için nasıl uygulamalıyım?
davidlee

Süper :) Gerçekten bir cazibe gibi çalıştı. Spring MVC
SKaul

115

Yukarıda çok net değil, ancak PHP'de istek alıyorsanız kullanabilirsiniz:

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

PHP'de bir diziye AngularJS POST'tan erişmek için.


3
Onunla $ _POST dizisinin üzerine yazarken bir diziye zorlamak için true eklemek gerekiyordu. json_decode(file_get_contents('php://input'), true);
Jon

4
@Zalaboza, herhangi bir çözümün 'evrensel' olarak kabul edilmesinin zor olduğunu kabul ediyorum ama 'hacky' olduğu konusunda hemfikir değilim --- php.net devletler: "file_get_contents () içeriği okumak için tercih edilen yoldur Performansı artırmak için işletim sisteminiz tarafından destekleniyorsa bellek eşleme tekniklerini kullanır. " Bu durumda bir dosya okumadığımız halde yine de yayınlanan json verilerini okuyoruz. Okuyucuların (ben de dahil) bu konuda daha iyi bir karar vermelerine yardımcı olmak için yeni bir yanıta katkıda bulunabilmeniz veya yeni bilgiler vermeniz harika olurdu.
Don F

78

Varsayılan "İçerik Türü" nü şu şekilde ayarlayabilirsiniz:

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

Hakkında databiçimi:

$ Http.post ve $ http.put yöntemleri, veri parametresi olarak herhangi bir JavaScript nesnesi (veya dize) değerini kabul eder. Veriler bir JavaScript nesnesiyse, varsayılan olarak bir JSON dizesine dönüştürülür.

Bu varyasyonu kullanmaya çalışın

function sendData($scope) {
    $http({
        url: 'request-url',
        method: "POST",
        data: { 'message' : message }
    })
    .then(function(response) {
            // success
    }, 
    function(response) { // optional
            // failed
    });
}

9
Çalışmıyor gibi görünüyor. Ben sadece dize ve: başlıkları olarak verileri ile varyasyon denedim: {'Content-Type': 'application / x-www-form-urlencoded'} - ve bu işe yarıyor gibi görünüyor, ama daha iyi bir yolu var mı o?
Spencer Mark

2
Varsayılan içerik türünü yukarıda açıklandığı gibi ayarlayın ve veriler için js nesnesi kullanılmaz. Bunun gibi dize kullanın: 'message =' + message Benim için çalışıyor
gSorry

58

Benzer bir sorun yaşadım ve bunun da yararlı olup olmadığını merak ediyorum: https://stackoverflow.com/a/11443066

var xsrf = $.param({fkey: "key"});
$http({
    method: 'POST',
    url: url,
    data: xsrf,
    headers: {'Content-Type': 'application/x-www-form-urlencoded'}
})

Saygılarımızla,


İhtiyacımız olan tek değişiklik, başlıklar gibi görünüyor. Teşekkür ederim!
Ben Guthrie

Teşekkürler, benim için yaptı :) Sorun POST verilerinin kodlanması oldu.
Daan

33

Parametre sonrası nesneleri dönüştürmek için bir işlev kullanmayı seviyorum.

myobject = {'one':'1','two':'2','three':'3'}

Object.toparams = function ObjecttoParams(obj) {
    var p = [];
    for (var key in obj) {
        p.push(key + '=' + encodeURIComponent(obj[key]));
    }
    return p.join('&');
};

$http({
    method: 'POST',
    url: url,
    data: Object.toparams(myobject),
    headers: {'Content-Type': 'application/x-www-form-urlencoded'}
})

30

Bu nihayet $ httpParamSerializerJQLike kullanılarak açısal 1.4'te ele alınmıştır.

Bkz. Https://github.com/angular/angular.js/issues/6039

.controller('myCtrl', function($http, $httpParamSerializerJQLike) {
$http({
  method: 'POST',
  url: baseUrl,
  data: $httpParamSerializerJQLike({
    "user":{
      "email":"wahxxx@gmail.com",
      "password":"123456"
    }
  }),
  headers:
    'Content-Type': 'application/x-www-form-urlencoded'
})})

Sorunla karşılaşıyorum POST 192.168.225.75:7788/procure/p/search 400 (Hatalı İstek)
Anuj

19

Kullandığım jQuery param ile angularjs sonrası requrest. İşte bir örnek ... HTML kodunuzda myapptanımlanan AngularJS uygulama modülünü oluşturun ng-app.

var app = angular.module('myapp', []);

Şimdi bir Login kontrolörü ve POST e-postası ve şifresi oluşturalım.

app.controller('LoginController', ['$scope', '$http', function ($scope, $http) {
    // default post header
    $http.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8';
    // send login data
    $http({
        method: 'POST',
        url: 'https://example.com/user/login',
        data: $.param({
            email: $scope.email,
            password: $scope.password
        }),
        headers: {'Content-Type': 'application/x-www-form-urlencoded'}
    }).success(function (data, status, headers, config) {
        // handle success things
    }).error(function (data, status, headers, config) {
        // handle error things
    });
}]);

Ben kodu exaplain sevmiyorum, anlamak için yeterince basit :) Not bu paramjQuery, bu yüzden çalışması için hem jQuery hem de AngularJS yüklemeniz gerekir. İşte bir ekran görüntüsü.

resim açıklamasını buraya girin

Umarım bu yardımcı olur. Teşekkürler!


10

AngularJS ve Node.js + Express 4 + Router ile aynı sorunu yaşadım

Yönlendirici, gönderinin gövde içindeki isteğinden veri bekler. Açısal Dokümanlar'daki örneği izlersem bu gövde her zaman boştu

Gösterim 1

$http.post('/someUrl', {msg:'hello word!'})

Ama verilerde kullandıysam

Gösterim 2

$http({
       withCredentials: false,
       method: 'post',
       url: yourUrl,
       headers: {'Content-Type': 'application/x-www-form-urlencoded'},
       data: postData
 });

Düzenleme 1:

Aksi takdirde node.js yönlendirici, gösterim 1 kullanılırsa req.body'deki verileri bekler:

req.body.msg

Bu da bilgileri JSON yükü olarak gönderir. Json'unuzda dizilerin olduğu bazı durumlarda bu daha iyidir ve x-www-form-urlencoded bazı sorunlar verecektir.

işe yaradı. Umarım yardımcı olur.


10

JQuery'den farklı olarak ve bilgiçlik uğruna Angular, istemciden sunucuya POST veri aktarımı için JSON biçimini kullanır (JQuery, xQuery ve urgular kodlanmış olsa da, JQuery ve Angular veri girişi için JSON kullanıyor olsa da). Bu nedenle, sorunun iki bölümü vardır: js istemci bölümünde ve sunucu bölümünde. Yani ihtiyacın var:

  1. js Açısal istemci bölümünü şöyle yerleştirin:

    $http({
    method: 'POST',
    url: 'request-url',
    data: {'message': 'Hello world'}
    });

VE

  1. bir istemciden veri almak için sunucu kısmınıza yazın (php ise).

            $data               = file_get_contents("php://input");
            $dataJsonDecode     = json_decode($data);
            $message            = $dataJsonDecode->message;
            echo $message;     //'Hello world'

Not: $ _POST çalışmaz!

Çözüm benim için iyi, umarım ve sizin için çalışır.


8

$httpAngularjs ile Post yöntemi ile veri göndermek için değiştirmeniz gerekir

data: "message=" + message, ile data: $.param({message:message})


1
AngularJS mesaj verisi gönderilirken data: $ .param neden gereklidir?
mavi gökyüzü

7

@ Felipe-miosso'nun cevabı üzerine inşa etmek için:

  1. Buradan AngularJS modülü olarak indirin ,
  2. Yükle
  3. Uygulamanıza ekleyin:

    var app = angular.module('my_app', [ ... , 'httpPostFix']);

6

Yorum yapmak için itibarım yok, ama Don F'nin cevabına yanıt olarak / ek olarak:

$params = json_decode(file_get_contents('php://input'));

İlişkili bir diziyi düzgün bir şekilde döndürmek trueiçin json_decodeişleve ikinci bir parametrenin eklenmesi gerekir:

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


6

Açısal

  var payload = $.param({ jobId: 2 });

                this.$http({
                    method: 'POST',
                    url: 'web/api/ResourceAction/processfile',
                    data: payload,
                    headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
                });

WebAPI 2

public class AcceptJobParams
        {
            public int jobId { get; set; }
        }

        public IHttpActionResult ProcessFile([FromBody]AcceptJobParams thing)
        {
            // do something with fileName parameter

            return Ok();
        }

5

Bu kod benim için sorunu çözdü. Uygulama düzeyinde bir çözümdür:

moduleName.config(['$httpProvider',
  function($httpProvider) {
    $httpProvider.defaults.transformRequest.push(function(data) {
        var requestStr;
        if (data) {
            data = JSON.parse(data);
            for (var key in data) {
                if (requestStr) {
                    requestStr += "&" + key + "=" + data[key];
                } else {
                    requestStr = key + "=" + data[key];
                }
            }
        }
        return requestStr;
    });
    $httpProvider.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded";
  }
]);

5

Bunu js dosyanıza ekleyin:

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

ve bunu sunucu dosyanıza ekleyin:

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

Bu işe yaramalı.


4

Ben de benzer bir sorunla karşılaştım ve böyle bir şey yapıyordum ve bu işe yaramadı. Yay denetleyicim veri parametresini okuyamadı.

var paramsVal={data:'"id":"1"'};
  $http.post("Request URL",  {params: paramsVal});  

Ama bu forum ve API Doc okurken, aşağıdaki şekilde denedim ve bu benim için çalıştı. Bazılarının da benzer bir sorunu varsa, aşağıda da deneyebilirsiniz.

$http({
      method: 'POST',
      url: "Request URL",           
      params: paramsVal,
      headers: {'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'}
            });

Param config'in ne yaptığını öğrenmek için lütfen https://docs.angularjs.org/api/ng/service/ $ http # post'a bakın. {data: '"id": "1"'} - URL'ye dönüştürülecek dizelerin veya nesnelerin haritası? data = "id: 1"


4

Bu muhtemelen geç bir cevap ama en uygun yolu aynı parça açısal kullanımı bir "get" isteği yaparken kullanarak $httpParamSerializerkontrol etmek için enjekte etmek zorunda kalacak şekilde kullanmak olduğunu düşünüyorum hiç Jquery kullanın, $http.post(url,$httpParamSerializer({param:val}))

app.controller('ctrl',function($scope,$http,$httpParamSerializer){
    $http.post(url,$httpParamSerializer({param:val,secondParam:secondVal}));
}

4

Benim durumumda sorunu şu şekilde çözüyorum:

var deferred = $q.defer();

$http({
    method: 'POST',
    url: 'myUri', 
    data: $.param({ param1: 'blablabla', param2: JSON.stringify(objJSON) }),
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
}).then(
    function(res) {
        console.log('succes !', res.data);
        deferred.resolve(res.data);
    },
    function(err) {
        console.log('error...', err);
        deferred.resolve(err);
    }
);
return deferred.promise;

Bir JSON nesnesi içeren her parametre için JSON.stringify kullanmanız ve ardından veri nesnenizi "$ .param" :-) ile oluşturmanız gerekir :-)

Not: Benim "objJSON" dizi, tamsayı, dize ve html içeriği içeren bir JSON nesnesidir. Toplam büyüklüğü> 3500 karakterdir.


3

Cevabı kabul ettiğini biliyorum . Ancak, cevap herhangi bir nedenden dolayı onlara uymuyorsa, takip etmek gelecekteki okuyuculara yardımcı olabilir.

Angular, jQuery ile aynı ajax yapmaz. Açısal değiştirmek için kılavuzu takip etmeye çalışırken $httpprovider, başka sorunlarla karşılaştım. Örneğin,$this->input->is_ajax_request() fonksiyonun her zaman başarısız (başka bir programcı tarafından yazılmış ve küresel olarak kullanılan, bu yüzden değişemez) kodigniter kullanın bu gerçek ajax isteği değildi.

Çözmek için ertelenmiş sözden yardım aldım . Firefox'ta test ettim ve ie9 ve işe yaradı.

Herhangi bir açısal kod dışında tanımlanan aşağıdaki işlevi var . Bu işlev düzenli jquery ajax çağrısı yapar ve ertelenmiş / söz (hala öğreniyorum) nesnesini döndürür.

function getjQueryAjax(url, obj){
    return $.ajax({
        type: 'post',
        url: url,
        cache: true,
        data: obj
    });
}

Sonra aşağıdaki kodu kullanarak açısal kod çağırıyorum. $scopeManuel olarak güncellememiz gerektiğini lütfen unutmayın $scope.$apply().

    var data = {
        media: "video",
        scope: "movies"
    };
    var rPromise = getjQueryAjax("myController/getMeTypes" , data);
    rPromise.success(function(response){
        console.log(response);
        $scope.$apply(function(){
            $scope.testData = JSON.parse(response);
            console.log($scope.testData);
        });
    }).error(function(){
        console.log("AJAX failed!");
    });

Bu mükemmel bir cevap olmayabilir, ancak jquery ajax çağrılarını açısal ile kullanmama ve güncellememe izin verdi $scope.


2
Açısal 1.3'ten beri $ q adlı kendi vaat hizmeti vardır. Bir gönderi için JQuery kullanmaya gerek yok.
mbokil

3

Ben ekspres aynı sorunu vardı .. çözmek için http istekleri göndermeden önce json nesneleri ayrıştırmak için bodyparser kullanmak zorunda ..

app.use(bodyParser.json());

3

Açısal js ve çalıştı aşağıda kodu ile asp.net WCF webservices kullanıyorum:

 $http({
        contentType: "application/json; charset=utf-8",//required
        method: "POST",
        url: '../../operation/Service.svc/user_forget',
        dataType: "json",//optional
        data:{ "uid_or_phone": $scope.forgettel, "user_email": $scope.forgetemail },
        async: "isAsync"//optional

       }).success( function (response) {

         $scope.userforgeterror = response.d;                    
       })

Umarım yardımcı olur.


3

Sunucuya veri göndermek için $ http.post yönteminin nasıl kullanılacağına ve bu durumda neden çalışmadığına dair tam bir kod snippet'i bulunamadı.

Aşağıdaki kod snippet'inin açıklamaları ...

  1. Www sonrası veri JSON verileri serileştirmek için jQuery $ .param işlevini kullanıyorum
  2. Sunucuya www post formatında veri gönderdiğimizi bildiren angularJS $ http.post isteği ile birlikte geçirilecek yapılandırma değişkeninde İçerik Türünü ayarlama.

  3. Ben url olarak 1. parametre, veri (serileştirilmiş) olarak 2. parametre ve config olarak 3. parametre göndermek $ htttp.post yöntemi dikkat edin.

Kalan kod kendiliğinden anlaşılır.

$scope.SendData = function () {
           // use $.param jQuery function to serialize data from JSON 
            var data = $.param({
                fName: $scope.firstName,
                lName: $scope.lastName
            });

            var config = {
                headers : {
                    'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8;'
                }
            }

            $http.post('/ServerRequest/PostDataResponse', data, config)
            .success(function (data, status, headers, config) {
                $scope.PostDataResponse = data;
            })
            .error(function (data, status, header, config) {
                $scope.ResponseDetails = "Data: " + data +
                    "<hr />status: " + status +
                    "<hr />headers: " + header +
                    "<hr />config: " + config;
            });
        };

$ Http.post yönteminin kod örneğine buradan bakın .



3

Kullanılıyorsa Açısal> = 1.4 , burada kullanarak en temiz çözüm açısal tarafından sağlanan seri hale :

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

Ve sonra bunu uygulamanızın herhangi bir yerinde yapabilirsiniz:

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

Ve doğru olarak serileştirip edecek param1=value1&param2=value2ve onu göndermek /requesturlileapplication/x-www-form-urlencoded; charset=utf-8 normalde uç noktaları üzerinde POST istekleri ile beklenen olarak Content-Type başlığına.

TL; DR

Araştırmam sırasında bu sorunun cevabının birçok farklı çeşide geldiğini buldum; bazıları çok kıvrımlıdır ve özel işlevlere bağlıdır, bazıları jQuery'ye bağlıdır ve bazıları sadece üstbilgiyi ayarlamanız gerektiğini önermek için eksiktir.

Content-TypeÜstbilgiyi yeni ayarlarsanız, bitiş noktası POST verilerini görür, ancak standart biçimde olmayacaktır, çünküdata veya veri nesnenizi manuel olarak serileştirmezseniz, hepsi JSON olarak serileştirilir varsayılan değerdir ve bitiş noktasında yanlış yorumlanabilir.

örneğin, yukarıdaki örnekte doğru serileştirici ayarlanmamışsa, bitiş noktasında şu şekilde görünecektir:

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

Bu da beklenmedik ayrıştırmaya yol açabilir, örneğin ASP.NET bunu nullparametre adı olarak, {"param1":"value1","param2":"value2"}değer olarak kabul eder; veya Fiddler bunu {"param1":"value1","param2":"value2"}parametre adı ve nulldeğer olarak başka bir şekilde yorumlar .


3

OP'nin önerilen çalışma formatı ve Denison'un cevabına benzer şekilde, $http.postsadece yerine kullanmak yerine $httpve hala jQuery'ye bağımlıdır.

Burada jQuery kullanma hakkında iyi bir şey karmaşık nesneler düzgün geçirilir olduğunu; manuel olarak verileri bozabilecek URL parametrelerine dönüştürmeye karşı.

$http.post( 'request-url', jQuery.param( { 'message': message } ), {
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
});

2

Ne zaman bu sorun vardı ben gönderme parametre basit bir nesne yerine nesnelerin bir dizi olduğu ortaya çıktı.


2

Açısal 1.2'den 1.3'e güncellenen kodda bir sorun bulduk. Bir kaynağı dönüştürmek sonsuz bir döngüye yol açacaktır çünkü (sanırım) $ sözünü tekrar aynı nesneyi tutarak. Belki birisine yardım eder ...

Bunu şu şekilde düzeltebilirim:

[...]
  /**
 * The workhorse; converts an object to x-www-form-urlencoded serialization.
 * @param {Object} obj
 * @return {String}
 */
var param = function (obj) {
var query = '', name, value, fullSubName, subName, subValue, innerObj, i;

angular.forEach(obj, function(value, name) {
+    if(name.indexOf("$promise") != -1) {
+        return;
+    }

    value = obj[name];
    if (value instanceof Array) {
        for (i = 0; i < value.length; ++i) {
[...]

2

Bir süredir kabul edilen cevap kodunu (Felipe'nin kodu) kullanıyorum ve harika çalışıyor (teşekkürler Felipe!).

Ancak, son zamanlarda boş nesneler veya dizilerle ilgili sorunları olduğunu keşfettim. Örneğin, bu nesneyi gönderirken:

{
    A: 1,
    B: {
        a: [ ],
    },
    C: [ ],
    D: "2"
}

PHP, B ve C'yi hiç görmüyor. Bunu alır:

[
    "A" => "1",
    "B" => "2"
]

Chrome'daki asıl talebe bir göz attığınızda şunu gösterir:

A: 1
:
D: 2

Alternatif bir kod pasajı yazdım. Kullanım durumlarımda iyi çalışıyor gibi görünüyor ama kapsamlı bir şekilde test etmedim, bu yüzden dikkatli kullanın.

Güçlü yazmayı sevdiğim için TypeScript kullandım, ancak saf JS'ye dönüştürmek kolay olurdu:

angular.module("MyModule").config([ "$httpProvider", function($httpProvider: ng.IHttpProvider) {
    // Use x-www-form-urlencoded Content-Type
    $httpProvider.defaults.headers.post["Content-Type"] = "application/x-www-form-urlencoded;charset=utf-8";

    function phpize(obj: Object | any[], depth: number = 1): string[] {
        var arr: string[] = [ ];
        angular.forEach(obj, (value: any, key: string) => {
            if (angular.isObject(value) || angular.isArray(value)) {
                var arrInner: string[] = phpize(value, depth + 1);
                var tmpKey: string;
                var encodedKey = encodeURIComponent(key);
                if (depth == 1) tmpKey = encodedKey;
                else tmpKey = `[${encodedKey}]`;
                if (arrInner.length == 0) {
                    arr.push(`${tmpKey}=`);
                }
                else {
                    arr = arr.concat(arrInner.map(inner => `${tmpKey}${inner}`));
                }
            }
            else {
                var encodedKey = encodeURIComponent(key);
                var encodedValue;
                if (angular.isUndefined(value) || value === null) encodedValue = "";
                else encodedValue = encodeURIComponent(value);

                if (depth == 1) {
                    arr.push(`${encodedKey}=${encodedValue}`);
                }
                else {
                    arr.push(`[${encodedKey}]=${encodedValue}`);
                }
            }
        });
        return arr;
    }

    // Override $http service's default transformRequest
    (<any>$httpProvider.defaults).transformRequest = [ function(data: any) {
        if (!angular.isObject(data) || data.toString() == "[object File]") return data;
        return phpize(data).join("&");
    } ];
} ]);

Felipe'nin kodundan daha az verimlidir, ancak HTTP isteğinin genel yüküne kıyasla hemen olması gerektiği için çok önemli olduğunu düşünmüyorum.

Şimdi PHP gösteriyor:

[
    "A" => "1",
    "B" => [
        "a" => ""
    ],
    "C" => "",
    "D" => "2"
]

Bildiğim kadarıyla PHP'nin Ba ve C'nin boş diziler olduğunu tanımasını sağlamak mümkün değil, ama en azından anahtarlar ortaya çıkıyor, bu da aslında içeride boş olsa bile belirli bir yapıya dayanan bir kod olduğunda önemlidir.

Ayrıca undefined ve null değerlerini boş dizelere dönüştürdüğünü de unutmayın .


JavaScript ile POO'da kodlamanın en iyi yolu TypeScript!
çirkinleştirmek

2

Göndermek istediğiniz verileri ikinci parametre olarak eklemeniz yeterlidir:

$http.post('request-url',  message);

Aynı zamanda çalışan başka bir form:

$http.post('request-url',  { params: { paramName: value } });

paramNameAradığınız işlevin parametresinin adıyla tam olarak eşleştiğinden emin olun .

Kaynak: AngularJS post shortcut method


5
Herkes bu cevabın neden oylandığını açıklayabilir mi?
Marco Lackovic


1

Bunu aşağıdaki kodlarla çözdüm:

İstemci Tarafı (Js):

     $http({
                url: me.serverPath,
                method: 'POST',
                data: data,
                headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
            }).
                success(function (serverData) {
                    console.log("ServerData:", serverData);
    ......

verilerin bir nesne olduğuna dikkat edin.

Sunucuda (ASP.NET MVC):

[AllowCrossSiteJson]
        public string Api()
        {
            var data = JsonConvert.DeserializeObject<AgentRequest>(Request.Form[0]);
            if (data == null) return "Null Request";
            var bl = Page.Bl = new Core(this);

            return data.methodName;
        }

ve alanlar arası talepler için 'AllowCrossSiteJsonAttribute' gereklidir:

public class AllowCrossSiteJsonAttribute : ActionFilterAttribute
    {
        public override void OnActionExecuting(ActionExecutingContext filterContext)
        {
            filterContext.RequestContext.HttpContext.Response.AddHeader("Access-Control-Allow-Origin", "*");
            base.OnActionExecuting(filterContext);
        }
    }

Umarım faydalı olmuştur.

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.