AngularJs $ http.post () tidak mengirim data

337

Adakah yang bisa memberi tahu saya mengapa pernyataan berikut tidak mengirim data pos ke url yang ditentukan? Url dipanggil tetapi di server ketika saya mencetak $ _POST - Saya mendapatkan array kosong. Jika saya mencetak pesan di konsol sebelum menambahkannya ke data - itu menunjukkan konten yang benar.

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

Saya juga sudah mencobanya dengan data sebagai string (dengan hasil yang sama):

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

Tampaknya berfungsi ketika saya menggunakannya dalam format berikut:

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

tetapi apakah ada cara untuk melakukannya dengan $ http.post () - dan apakah saya harus selalu menyertakan header agar dapat berfungsi? Saya percaya bahwa tipe konten di atas menentukan format data yang dikirim, tetapi dapatkah saya mengirimkannya sebagai objek javascript?

Spencer Mark
sumber
Apakah url dalam asal yang sama?
fmquaglia
Maaf - ya untuk semua contoh, url yang sama
Spencer Mark
@SpencerMark maaf .. saya mencoba di atas kode kerja Anda .. tidak bekerja untuk saya.
Arul Sidthan

Jawaban:

346

Saya memiliki masalah yang sama dengan menggunakan asp.net MVC dan menemukan solusinya di sini

Ada banyak kebingungan di antara para pendatang baru di AngularJS tentang mengapa $httpfungsi singkatan layanan ( $http.post(), dll.) Tampaknya tidak dapat ditukar dengan persamaan jQuery ( jQuery.post(), dll.)

Perbedaannya terletak pada bagaimana jQuery dan AngularJS membuat serial dan mengirimkan data. Pada dasarnya, masalahnya terletak pada bahasa server pilihan Anda karena tidak dapat memahami transmisi AngularJS secara asli ... Secara default, jQuery mentransmisikan data menggunakan

Content-Type: x-www-form-urlencoded

dan foo=bar&baz=moeserialisasi yang akrab .

AngularJS , bagaimanapun, mentransmisikan data menggunakan

Content-Type: application/json 

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

Serialisasi JSON, yang sayangnya beberapa bahasa server Web - terutama PHP - tidak di-unserialize secara native.

Bekerja seperti pesona.

KODE

// 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;
  }];
});
Felipe Miosso
sumber
7
Saya telah menambahkan skrip ini ke bower, gunakan bower install angular-post-fix --save-devuntuk menambahkannya.
Billy Blaze
begitu juga ada cara untuk mengubah metode data pengiriman php. Karena itulah masalah yang saya alami saat ini.
Demodave
1
Kode ini berfungsi dengan baik pada sebagian besar bagian, tetapi saya pernah mengalami masalah saat mengirimkan hierarki objek kosong atau bahkan nilai kosong datar. Misalnya, {a: 1, b: {c: {d: {}}}, e: tidak terdefinisi, f: null, g: 2} tidak akan dikodekan dengan benar, dan PHP akan mendapatkannya sebagai ["a" = > "1", "g" => "2"]. Seluruh struktur di bawah "b", serta "e" dan "f", termasuk kunci itu sendiri - akan hilang. Saya memposting kode alternatif di bawah ini, dengan mana struktur di atas akan diterjemahkan sebagai: ["a" => "1", "b" => ["c" => ["d" => ""]], "e" => "", "f" => "", "g" => "2"].
obe
1
bagaimana seharusnya saya menerapkan ini untuk multi-data / formulir?
davidlee
Luar biasa :) Memang bekerja seperti pesona. Saya menghadapi masalah dengan Spring MVC
SKaul
115

Tidak terlalu jelas di atas, tetapi jika Anda menerima permintaan dalam PHP, Anda dapat menggunakan:

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

Untuk mengakses array dalam PHP dari AngularJS POST.

Don F
sumber
3
Saya perlu menambahkan true untuk memaksanya ke array ketika menimpa array $ _POST dengannya. json_decode(file_get_contents('php://input'), true);
Jon
4
@Zalaboza, saya akan setuju bahwa sulit untuk memiliki solusi yang dianggap 'universal' tapi saya tidak setuju bahwa itu 'hacky' --- php.net menyatakan: "file_get_contents () adalah cara yang disukai untuk membaca konten file menjadi string. Ini akan menggunakan teknik pemetaan memori jika didukung oleh OS Anda untuk meningkatkan kinerja. " Memang kami tidak membaca file dalam situasi ini tetapi kami masih membaca data json yang diposting. Alangkah baiknya jika Anda dapat menyumbangkan jawaban baru atau memberikan informasi baru untuk membantu pembaca (termasuk saya) membuat keputusan yang lebih baik tentang ini.
Don F
78

Anda dapat mengatur "Tipe-Konten" default seperti ini:

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

Tentang dataformat:

Metode $ http.post dan $ http.put menerima nilai objek JavaScript (atau string) apa pun sebagai parameter data mereka. Jika data adalah objek JavaScript, secara default, akan dikonversi ke string JSON.

Coba gunakan variasi ini

function sendData($scope) {
    $http({
        url: 'request-url',
        method: "POST",
        data: { 'message' : message }
    })
    .then(function(response) {
            // success
    }, 
    function(response) { // optional
            // failed
    });
}
Denison Luz
sumber
9
Sepertinya tidak berhasil. Saya baru saja mencoba variasi dengan data sebagai string dan: header: {'Content-Type': 'application / x-www-form-urlencoded'} - dan sepertinya berhasil, tetapi apakah ada cara yang lebih baik untuk melakukan Itu?
Spencer Mark
2
Tetapkan tipe konten default seperti dijelaskan di atas dan untuk data tidak menggunakan objek js. Gunakan string seperti ini: 'message =' + message Bekerja untuk saya
gSorry
58

Saya memiliki masalah serupa, dan saya ingin tahu apakah ini dapat berguna juga: 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'}
})

Salam,

ericson.cepeda
sumber
Sepertinya header adalah satu-satunya perubahan yang kami butuhkan. Terima kasih!
Ben Guthrie
Terima kasih, itu berhasil untuk saya :) Masalahnya adalah penyandian data POST.
Daan
33

Saya suka menggunakan fungsi untuk mengonversi objek ke posting params.

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'}
})
Rômulo Collopy
sumber
30

Ini akhirnya dialamatkan dalam sudut 1.4 menggunakan $ httpParamSerializerJQLike

Lihat https://github.com/angular/angular.js/issues/6039

.controller('myCtrl', function($http, $httpParamSerializerJQLike) {
$http({
  method: 'POST',
  url: baseUrl,
  data: $httpParamSerializerJQLike({
    "user":{
      "email":"[email protected]",
      "password":"123456"
    }
  }),
  headers:
    'Content-Type': 'application/x-www-form-urlencoded'
})})
Stetzon
sumber
Saya menghadapi masalah POST 192.168.225.75:7788/procure/p/search 400 (Permintaan Buruk)
Anuj
19

Saya menggunakan param jQuery dengan AngularJS post requrest. Ini adalah contohnya ... buat modul aplikasi AngularJS, di mana myappdidefinisikan dengan ng-appdalam kode HTML Anda.

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

Sekarang mari kita membuat pengontrol Login dan POST email dan kata sandi.

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

Saya tidak suka menjelaskan kode, ini cukup sederhana untuk dimengerti :) Perhatikan bahwa paramini dari jQuery, jadi Anda harus menginstal jQuery dan AngularJS untuk membuatnya berfungsi. Ini screenshotnya.

masukkan deskripsi gambar di sini

Semoga ini bisa membantu. Terima kasih!

Madan Sapkota
sumber
10

Saya memiliki masalah yang sama dengan AngularJS dan Node.js + Express 4 + Router

Router mengharapkan data dari permintaan posting di tubuh. Badan ini selalu kosong jika saya mengikuti contoh dari Angular Docs

Notasi 1

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

Tetapi jika saya menggunakannya dalam data

Notasi 2

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

Edit 1:

Jika tidak, router node.js akan mengharapkan data dalam req.body jika menggunakan notasi 1:

req.body.msg

Yang juga mengirimkan informasi sebagai muatan JSON. Ini lebih baik dalam beberapa kasus di mana Anda memiliki array di json Anda dan x-www-form-urlencoded akan memberikan beberapa masalah.

itu berhasil. Semoga ini bisa membantu.

tahu bagaimana
sumber
10

Tidak seperti JQuery dan demi pedantry, Angular menggunakan format JSON untuk transfer data POST dari klien ke server (JQuery mungkin menggunakan urlencoded x-www-form mungkin, meskipun JQuery dan Angular menggunakan JSON untuk imput data). Oleh karena itu ada dua bagian masalah: di bagian js client dan di bagian server Anda. Jadi, Anda perlu:

  1. cantumkan bagian klien Angular seperti ini:

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

DAN

  1. tulis di bagian server Anda untuk menerima data dari klien (jika itu adalah php).

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

Catatan: $ _POST tidak akan berfungsi!

Solusinya bekerja untuk saya baik-baik saja, semoga, dan untuk Anda.

Roma
sumber
8

Untuk mengirim data melalui metode Post dengan $httpangularjs Anda perlu mengubah

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

BERGUIGA Mohamed Amine
sumber
1
mengapa data: $ .param diperlukan saat mengirim data posting AngularJS?
biru-langit
7

Untuk membangun jawaban @ felipe-miosso:

  1. Unduh sebagai modul AngularJS dari sini ,
  2. Pasang itu
  3. Tambahkan ke aplikasi Anda:

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

Saya tidak memiliki reputasi untuk berkomentar, tetapi sebagai tanggapan / tambahan atas jawaban Don F:

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

Parameter kedua trueperlu ditambahkan ke json_decodefungsi untuk mengembalikan array asosiatif dengan benar:

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

Esten
sumber
6

Sudut

  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();
        }
Malcolm Swaine
sumber
5

Kode ini memecahkan masalah bagi saya. Ini adalah solusi tingkat aplikasi:

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";
  }
]);
Spartak Lalaj
sumber
5

Tambahkan ini di file js Anda:

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

dan tambahkan ini ke file server Anda:

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

Itu seharusnya bekerja.

Yesus Erwin Suarez
sumber
4

Saya juga menghadapi masalah yang sama dan saya melakukan sesuatu seperti ini dan itu tidak berhasil. Pengontrol Pegas saya tidak dapat membaca parameter data.

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

Tetapi membaca forum ini dan API Doc, saya mencoba mengikuti dan itu berhasil bagi saya. Jika seseorang juga memiliki masalah serupa, Anda dapat mencoba di bawah ini juga.

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

Silakan periksa https://docs.angularjs.org/api/ng/service/ $ http # post untuk mengetahui apa yang param config lakukan. {data: '"id": "1"'} - Peta string atau objek yang akan diubah menjadi URL? data = "id: 1"

Viraj
sumber
4

ini mungkin jawaban yang terlambat tetapi saya pikir cara yang paling tepat adalah dengan menggunakan potongan kode yang sama dengan penggunaan sudut ketika melakukan permintaan "get" menggunakan Anda $httpParamSerializerharus menyuntikkannya ke controller Anda sehingga Anda bisa melakukan hal berikut tanpa harus gunakan Jquery sama sekali, $http.post(url,$httpParamSerializer({param:val}))

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

Dalam kasus saya, saya menyelesaikan masalah seperti ini:

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;

Anda perlu menggunakan JSON.stringify untuk setiap param yang berisi objek JSON, dan kemudian buat objek data Anda dengan "$ .param" :-)

NB: "objJSON" saya adalah objek JSON yang berisi konten array, integer, string, dan html. Ukuran totalnya> 3500 karakter.

bArraxas
sumber
3

Saya tahu sudah menerima jawaban. Tetapi, mengikuti mungkin membantu pembaca di masa depan, jika jawabannya tidak cocok untuk mereka dengan alasan apa pun.

Angular tidak melakukan ajax sama dengan jQuery. Sementara saya mencoba mengikuti panduan untuk memodifikasi sudut $httpprovider, saya menemukan masalah lain. Misalnya saya menggunakan codeigniter di mana $this->input->is_ajax_request()fungsi selalu gagal (yang ditulis oleh programmer lain dan digunakan secara global, jadi tidak bisa berubah) mengatakan ini bukan permintaan ajax nyata.

Untuk mengatasinya, saya mengambil bantuan janji yang ditangguhkan . Saya mengujinya di Firefox, dan ie9 dan berhasil.

Saya telah mengikuti fungsi yang didefinisikan di luar salah satu kode sudut. Fungsi ini membuat panggilan ajax jquery biasa dan mengembalikan objek ditangguhkan / janji (saya masih belajar).

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

Lalu saya menyebutnya kode sudut menggunakan kode berikut. Harap dicatat bahwa kami harus memperbarui $scopemenggunakan secara manual $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!");
    });

Ini mungkin bukan jawaban yang sempurna, tetapi memungkinkan saya untuk menggunakan panggilan ajax jquery dengan sudut dan memungkinkan saya untuk memperbarui $scope.

Nis
sumber
2
Angular memiliki layanan janji sendiri yang disebut $ q sejak 1.3. Tidak perlu menggunakan JQuery untuk posting.
mbokil
3

Saya punya masalah yang sama di express .. untuk menyelesaikannya Anda harus menggunakan bodyparser untuk mengurai objek json sebelum mengirim permintaan http ..

app.use(bodyParser.json());
Muhammad Soliman
sumber
3

Saya menggunakan layanan web asp.net WCF dengan js sudut dan kode di bawah ini berfungsi:

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

Semoga ini bisa membantu.

Mehdi Rostami
sumber
3

Tidak menemukan cuplikan kode lengkap tentang cara menggunakan metode $ http.post untuk mengirim data ke server dan mengapa itu tidak berfungsi dalam kasus ini.

Penjelasan cuplikan kode di bawah ini ...

  1. Saya menggunakan fungsi jQuery $ .param untuk membuat serialisasi data JSON menjadi data posting www
  2. Mengatur Content-Type dalam variabel config yang akan diteruskan bersama dengan permintaan angularJS $ http.post yang menginstruksikan server bahwa kami mengirim data dalam format postingan www.

  3. Perhatikan metode $ htttp.post, di mana saya mengirim parameter 1 sebagai url, parameter 2 sebagai data (serial) dan parameter ke-3 sebagai konfigurasi.

Kode yang tersisa dimengerti sendiri.

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

Lihatlah contoh kode metode $ http.post di sini .

Sheo Narayan
sumber
3

Jika Anda menggunakan PHP, ini adalah cara mudah untuk mengakses array dalam PHP dari AngularJS POST.

$params = json_decode(file_get_contents('php://input'),true);
Luis Felipe Barnett V
sumber
3

Jika menggunakan Angular> = 1.4 , inilah solusi terbersih menggunakan serializer yang disediakan oleh Angular :

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

Dan kemudian Anda bisa melakukan ini di mana saja di aplikasi Anda:

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

Dan itu akan membuat serialisasi data dengan benar param1=value1&param2=value2dan mengirimkannya ke /requesturldengan application/x-www-form-urlencoded; charset=utf-8header Tipe Konten seperti yang biasanya diharapkan dengan permintaan POST pada titik akhir.

TL; DR

Selama penelitian saya, saya menemukan bahwa jawaban untuk masalah ini datang dalam berbagai rasa; beberapa sangat berbelit-belit dan tergantung pada fungsi kustom, beberapa tergantung pada jQuery dan dan beberapa tidak lengkap dalam menyarankan bahwa Anda hanya perlu mengatur header.

Jika Anda hanya mengatur Content-Typeheader, titik akhir akan melihat data POST, tetapi itu tidak akan dalam format standar karena kecuali Anda memberikan string sebagai Andadata , atau secara manual membuat serial objek data Anda, semuanya akan diserialisasi sebagai JSON oleh default dan mungkin ditafsirkan secara salah di titik akhir.

misalnya jika serializer yang benar tidak diatur dalam contoh di atas, itu akan terlihat pada titik akhir sebagai:

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

Dan itu dapat menyebabkan penguraian yang tidak terduga, misalnya ASP.NET memperlakukannya sebagai nullnama parameter, dengan {"param1":"value1","param2":"value2"}sebagai nilai; atau Fiddler menafsirkannya dengan cara lain, dengan {"param1":"value1","param2":"value2"}sebagai nama parameter, dan nullsebagai nilai.

Saeb Amini
sumber
3

Mirip dengan format kerja yang disarankan OP & jawaban Denison, kecuali menggunakan $http.postbukan hanya $httpdan masih tergantung pada jQuery.

Hal yang baik tentang menggunakan jQuery di sini adalah objek kompleks dapat dilewati dengan benar; terhadap konversi secara manual menjadi parameter URL yang dapat memutarbalikkan data.

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

Ketika saya memiliki masalah ini, parameter yang saya posting ternyata menjadi array objek, bukan objek sederhana.

D. Kermott
sumber
2

Baru saja diperbarui dari sudut 1.2 ke 1.3, telah menemukan masalah dalam kode. Mengubah sumber daya akan menyebabkan loop tanpa akhir karena (saya pikir) dari $ berjanji memegang lagi objek yang sama. Mungkin itu akan membantu seseorang ...

Saya bisa memperbaikinya dengan:

[...]
  /**
 * 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) {
[...]
tom_w
sumber
2

Saya telah menggunakan kode jawaban yang diterima (kode Felipe) untuk sementara waktu dan sudah berfungsi dengan baik (terima kasih, Felipe!).

Namun, baru-baru ini saya menemukan bahwa ada masalah dengan objek atau array kosong. Misalnya, saat mengirimkan objek ini:

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

PHP sepertinya tidak melihat B dan C sama sekali. Mendapat ini:

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

Melihat permintaan aktual di Chrome menunjukkan ini:

A: 1
:
D: 2

Saya menulis cuplikan kode alternatif. Tampaknya berfungsi baik dengan kasus penggunaan saya, tetapi saya belum mengujinya secara ekstensif jadi gunakan dengan hati-hati.

Saya menggunakan TypeScript karena saya suka mengetik kuat tetapi akan mudah untuk mengkonversi ke JS murni:

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

Ini kurang efisien daripada kode Felipe tetapi saya tidak berpikir itu penting karena harus langsung dibandingkan dengan overhead keseluruhan permintaan HTTP itu sendiri.

Sekarang PHP menunjukkan:

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

Sejauh yang saya tahu itu tidak mungkin untuk mendapatkan PHP untuk mengenali bahwa Ba dan C adalah array kosong, tetapi setidaknya kunci muncul, yang penting ketika ada kode yang bergantung pada struktur tertentu bahkan ketika pada dasarnya kosong di dalamnya.

Perhatikan juga bahwa konversi s dan null s tidak terdefinisi menjadi string kosong.

obe
sumber
KetikScript cara terbaik untuk kode dalam POO dengan JavaScript!
Melumpuhkan
2

Masukkan saja data yang ingin Anda kirim sebagai parameter kedua:

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

Bentuk lain yang juga berfungsi adalah:

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

Pastikan yang paramNamesama persis dengan nama parameter fungsi yang Anda panggil.

Sumber: Metode pintas posting AngularJS

Marco Lackovic
sumber
5
Adakah yang bisa menjelaskan mengapa jawaban ini ditolak?
Marco Lackovic
1
Tidak ada cara bahwa solusi ini ditolak, itu yang paling sederhana, singkat dan terbukti dalam dokumentasi sudut docs.angularjs.org/api/ng/service/$http
ainasiart
1

Saya memecahkan ini dengan kode di bawah ini:

Sisi Klien (Js):

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

perhatikan bahwa data adalah objek.

Di server (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;
        }

dan 'AllowCrossSiteJsonAttribute' diperlukan untuk permintaan lintas domain:

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

Semoga ini bermanfaat.

pixparker
sumber