JQuery olmadan $ http ile urlencoded form verilerini POST nasıl?


195

AngularJS'de yeniyim ve bir başlangıç ​​için, sadece AngularJS kullanarak yeni bir uygulama geliştirmeyi düşündüm.

$httpBenim Angular App kullanarak sunucu tarafında bir AJAX çağrısı yapmaya çalışıyorum .

Parametreleri göndermek için aşağıdakileri denedim:

$http({
    method: "post",
    url: URL,
    headers: {'Content-Type': 'application/x-www-form-urlencoded'},
    data: $.param({username: $scope.userName, password: $scope.password})
}).success(function(result){
    console.log(result);
});

Bu çalışıyor, ancak jQuery de kullanıyor $.param. JQuery bağımlılığını kaldırmak için denedim:

data: {username: $scope.userName, password: $scope.password}

ama bu başarısız olmuş gibiydi. Sonra denedim params:

params: {username: $scope.userName, password: $scope.password}

ama bu da başarısız olmuş gibiydi. Sonra denedim JSON.stringify:

data: JSON.stringify({username: $scope.userName, password: $scope.password})

Görevime bu olası cevapları buldum, ancak başarısız oldu. Yanlış bir şey mi yapıyorum? Eminim, AngularJS bu işlevi sağlar, ama nasıl?


Asıl sorunun ne olduğunu bilmiyorum ama bunu denedin mi$http({method: 'post', url: URL, data: {username: $scope.userName, password: $scope.password}});
Mritunjay

1
İlk yönteminizin çalışması gerekir, $scope.userNametanımlanmış mı? Neden deneyin vermedi data: data?
Kevin B

@KevinB: üzgünüm .. Doğru düzenlemeyi yaptım.
Veer Shrivastav

@mritunjay: üzgünüm .. Düzenlemeyi yaptım .. Ben de aynısını deniyordum.
Veer Shrivastav

@Veer işe yaradı mı yoksa hala sorun mu yaşıyorsunuz?
V31

Yanıtlar:


409

Yapmanız gereken, verilerinizi nesneden JSON dizesine değil, url parametrelerine dönüştürmektir.

Ben Nadel'in blogundan .

Varsayılan olarak, $ http hizmeti, verileri JSON olarak serileştirip ardından "application / json" içerik türüyle göndererek giden isteği dönüştürür. Değeri bir FORM postası olarak göndermek istediğimizde, serileştirme algoritmasını değiştirmeli ve verileri "application / x-www-form-urlencoded" içerik türüyle kaydetmeliyiz.

Buradan bir örnek .

$http({
    method: 'POST',
    url: url,
    headers: {'Content-Type': 'application/x-www-form-urlencoded'},
    transformRequest: function(obj) {
        var str = [];
        for(var p in obj)
        str.push(encodeURIComponent(p) + "=" + encodeURIComponent(obj[p]));
        return str.join("&");
    },
    data: {username: $scope.userName, password: $scope.password}
}).then(function () {});

GÜNCELLEME

AngularJS V1.4 ile eklenen yeni hizmetleri kullanmak için, bkz.


41
JQuery kullanmadığınız için teşekkür ederiz!
OverMars

1
çok parçalı / form verisi göndermem gerekirse ne olur?
Dejell

2
Açısal jqLite gömülü olduğu sürece angular.element, sadecereturn angular.element.param(obj);
Vicary

4
@Vicary Param () işlevinin jqLite'de uygulanmadığını unutmayın - code.angularjs.org/1.3.14/docs/api/ng/function/angular.element
Alex Pavlov

1
Bu gitmek için başka bir yol var obj = {a: 1, b: 2}; Object.keys(obj).reduce(function(p, c) { return p.concat([encodeURIComponent(c) + "=" + encodeURIComponent(obj[c])]); }, []).join('&');
test30

137

Yalnızca AngularJS hizmetlerini kullanan URL kodlama değişkenleri

AngularJS 1.4 ve sonraki sürümlerde, iki hizmet POST istekleri için url kodlama verilerini işleyebilir ve verilerin transformRequestjQuery gibi harici bağımlılıklarla manipüle edilmesi veya kullanılması gereğini ortadan kaldırır :

  1. $httpParamSerializerJQLike- jQuery's'den esinlenen bir seri hale getirici .param()( önerilir )

  2. $httpParamSerializer - Angular'ın GET istekleri için kullandığı bir serileştirici

Örnek kullanım

$http({
  url: 'some/api/endpoint',
  method: 'POST',
  data: $httpParamSerializerJQLike($scope.appForm.data), // Make sure to inject the service you choose to the controller
  headers: {
    'Content-Type': 'application/x-www-form-urlencoded' // Note the appropriate header
  }
}).then(function(response) { /* do something here */ });

Daha ayrıntılı bir Plunker demosuna bakın


Nasıl $httpParamSerializerJQLikeve $httpParamSerializerfarklı

Genel olarak, karmaşık veri yapıları söz konusu $httpParamSerializerolduğunda $httpParamSerializerJQLikeolduğundan daha az "geleneksel" url kodlama formatı kullanır.

Örneğin (parantez kodlama yüzdesini yok saymak):

Bir diziyi kodlama

{sites:['google', 'Facebook']} // Object with array property

sites[]=google&sites[]=facebook // Result with $httpParamSerializerJQLike

sites=google&sites=facebook // Result with $httpParamSerializer

Bir nesneyi kodlama

{address: {city: 'LA', country: 'USA'}} // Object with object property

address[city]=LA&address[country]=USA // Result with $httpParamSerializerJQLike

address={"city": "LA", country: "USA"} // Result with $httpParamSerializer

Bunu bir fabrika içindeki $ kaynakta nasıl kullanabiliriz?
stilllife

2
Olmalı $http.({...yerine of`$http.post({...
Carlos Granados

@CarlosGranados Fark ettiğiniz için teşekkürler. Bu yazım hatası burada ve Plunker demosunda düzeltildi.
Boaz

Bu,
jQuery'den

4
Bu aradığım AngularJS'ye özel cevap. Keşke poster bunu en iyi cevap olarak seçseydi.
Marty Chang

61

Bunların hepsi aşırıya kaçıyor (ya da çalışmıyor) ... sadece bunu yap:

$http.post(loginUrl, `username=${ encodeURIComponent(username) }` +
                     `&password=${ encodeURIComponent(password) }` +
                     '&grant_type=password'
).success(function (data) {

11
Sonunda bazı sağduyu
jlewkovich

Bu, isteği yanlış içerik türü üstbilgisiyle göndermeyecek mi?
Phil

Benim için çalıştı ... başlığın ne olduğundan emin değilim, ancak istek çalıştı ve başarıyla kimlik doğrulamasına izin verdi. Neden test edip bize bildirmiyorsun.
Serj Sagan

5
@Phil Ben sunucuya bağlı olabilir, ben yapılandırma argümanı olarak {headers: {'Content-Type': 'application / x-www-form-urlencoded'}} ekleyene kadar kötü istek aldım $ http (config) yapıcı gibi moices 'yanıt gösterir. Her iki durumda da bu, sihirli bir dönüşüm getirmediği ve bazı yardımcı hizmetlerden birini gerektirmediği için kabul edilen cevaptan daha üstündür. Teşekkürler!
Bay Bungle

23

Sorun JSON dize biçimidir, Verilerde basit bir URL dizesi kullanabilirsiniz:

$http({
    method: 'POST',
    url: url,
    headers: {'Content-Type': 'application/x-www-form-urlencoded'},
    data: 'username='+$scope.userName+'&password='+$scope.password
}).success(function () {});

7
Eğer encodeURIComponent($scope.userName)verileri url kodlamak için kullanmak zorunda ya da kullanıcı gibi bir değer girerse parametreleriniz bozulacak"&myCustomParam=1"
Ivan Hušnjak

2
benim için işe yarayan tek cevap bu! Başarıyı
atladım

4

İşte olması gereken yol (ve lütfen arka uç değişiklikleri yok ... kesinlikle değil ... eğer ön yığının desteklemiyorsa application/x-www-form-urlencoded, atmak ... umarım AngularJS yapar!

$http({
     method: 'POST',
     url: 'api_endpoint',
     headers: {'Content-Type': 'application/x-www-form-urlencoded'},
     data: 'username='+$scope.username+'&password='+$scope.password
 }).then(function(response) {
    // on success
 }, function(response) {
    // on error
 });

AngularJS 1.5 ile cazibe gibi çalışır

İnsanlar, size bazı tavsiyelerde bulunalım:

  • (geri çekildikleri için) .then(success, error)uğraşırken $http, unutur .sucessve .errorgeri çağırırken sözler kullanın

  • Angularjs siteden burada " Artık geri arama parametre değeri gitmesi gereken yere belirtmek için yer tutucu olarak JSON_CALLBACK dizesi kullanabilirsiniz. "

Veri modeliniz yalnızca bir kullanıcı adı ve paroladan daha karmaşıksa, bunu yine de yapabilirsiniz (yukarıda önerildiği gibi)

$http({
     method: 'POST',
     url: 'api_endpoint',
     headers: {'Content-Type': 'application/x-www-form-urlencoded'},
     data: json_formatted_data,
     transformRequest: function(data, headers) {
          return transform_json_to_urlcoded(data); // iterate over fields and chain key=value separated with &, using encodeURIComponent javascript function
     }
}).then(function(response) {
  // on succes
}, function(response) {
  // on error
});

İçin belge buradaencodeURIComponent bulunabilir


3

Bir formsa üstbilgiyi şu şekilde değiştirmeyi deneyin:

headers[ "Content-type" ] = "application/x-www-form-urlencoded; charset=utf-8";

ve bir form ve basit bir json değilse bu başlığı deneyin:

headers[ "Content-type" ] = "application/json";

Hiçbir şey almıyorum. Hala boş bir $_POSTdizi aldım .!
Veer Shrivastav

Bu $ http çağrı kumandanızda mı?
V31

bir şey daha sunucu sonu php olduğunu?
V31

Ben de bir çözüm buldum @Veer hala sorunu alıyorsunuz?
V31

2
$http({

    method: "POST",
    url: "/server.php",
    headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
    data: "name='Олег'&age='28'",


}).success(function(data, status) {
    console.log(data);
    console.log(status);
});

4
Yalnızca kod yanıtları topluluk için yararlı değildir. Lütfen nasıl cevap
vereceğinize bakınız

1

Gönderen $ http docs bu çalışması gerekir ..

  $http.post(url, data,{headers: {'Content-Type': 'application/x-www-form-urlencoded'}})
    .success(function(response) {
         // your code...
     });

@Kevin bu konuda emin değilim ama ... bir dize göndermeyi denediğimde bana bir hata gösterdi
Srinath

@KevinB Fine..I anladım .. bir dize gönderilirken başlıkların değiştirilmesi gerektiğini düşünüyorum .. stackoverflow.com/a/20276775/2466168
Srinath

1
Not doğru gönderme olduğunu headersetkilemeyeceği datahala öyle ya da böyle urlencoded gerekecektir hangi.
Boaz

veriler hala json olarak gönderilir, sadece bir başlık ekleyerek verileri x-www-form-urlencoded içine kodlamanız gerekir
wendellmva

1

düz javascript nesnesi yayınlamanız gerekiyor, başka bir şey yok

           var request = $http({
                method: "post",
                url: "process.cfm",
                transformRequest: transformRequestAsFormPost,
                data: { id: 4, name: "Kim" }
            });

            request.success(
                function( data ) {
                    $scope.localData = data;
                }
            );

arka uç olarak php varsa o zaman biraz daha değişiklik yapmak gerekecek .. php sunucu tarafı düzeltmek için bu bağlantıyı kontrol


tam olarak ne istediğini değil, özellikle nasıl x-www-form-urlencoded olarak nasıl alabilir diye sordu, çünkü yayınlanan json şeyler ile ilgili sorunlar halinde çalışıyor.
ppetermann

@ppetermann downvoting önce sorunun düzenleme geçmişini kontrol ettiniz ..
harishr

1

Geç cevap olsa da, açısal UrlSearchParams'ın benim için çok iyi çalıştığını buldum, parametrelerin kodlanmasına da dikkat ediyor.

let params = new URLSearchParams();
params.set("abc", "def");

let headers = new Headers({ 'Content-Type': 'application/x-www-form-urlencoded'});
let options = new RequestOptions({ headers: headers, withCredentials: true });
this.http
.post(UrlUtil.getOptionSubmitUrl(parentSubcatId), params, options)
.catch();

0

Bu benim için çalıştı. Ön uç için açısal, arka uç için laravel php kullanıyorum. Projemde, açısal web json verilerini laravel arka ucuna gönderir.

Bu benim açısal kontrol cihazım.

var angularJsApp= angular.module('angularJsApp',[]);
angularJsApp.controller('MainCtrl', function ($scope ,$http) {

    $scope.userName ="Victoria";
    $scope.password ="password"


       $http({
            method :'POST',
            url:'http://api.mywebsite.com.localhost/httpTest?callback=JSON_CALLBACK',
            data: { username :  $scope.userName , password: $scope.password},
            headers: {'Content-Type': 'application/json'}
        }).success(function (data, status, headers, config) {
            console.log('status',status);
            console.log('data',status);
            console.log('headers',status);
        });

});

Bu benim php arka uç laravel denetleyicisidir.

public function httpTest(){
        if (Input::has('username')) {
            $user =Input::all();
            return  Response::json($user)->setCallback(Input::get('callback'));
        }
    }

Bu benim sıradan yönlendirme

Route::post('httpTest','HttpTestController@httpTest');

Tarayıcıda sonuç

durum 200
verileri JSON_CALLBACK ({"kullanıcı adı": "Victoria", "şifre": "şifre", "geri arama": "JSON_CALLBACK"}); httpTesting.js: 18 başlık işlevi (c) {a || (a = sc (b)); c? a [K (c)] || null: a} döndür

Postacı adı verilen krom uzantısı var. Arka uç URL'nizin çalışıp çalışmadığını test etmek için kullanabilirsiniz. https://chrome.google.com/webstore/detail/postman-rest-client/fdmmgilgnpjigdojojpjoooidkmcomcm?hl=en

umarım cevabım size yardımcı olacaktır.

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.