web-dev-qa-db-ja.com

どうやって POST jQueryなしで$ httpのurlencodedフォームデータ?

私はAngularJSに慣れていないので、最初はAngularJSのみを使用して新しいアプリケーションを開発することを考えました。

私のAJAX Appから$httpを使用して、サーバー側にAngular呼び出しをしようとしています。

パラメータを送信するために、私は以下を試しました:

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

これは動作していますが、$.paramでもjQueryを使用しています。 jQueryへの依存を取り除くために、私は試してみました:

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

しかしこれは失敗したようです。それから私はparamsを試しました:

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

しかしこれも失敗したようです。それから私はJSON.stringifyを試してみました:

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

私は私の探求にこれらの可能な答えを見つけました、しかし失敗しました。私は何か悪いことをしていますか? AngularJSがこの機能を提供すると確信していますが、どうすればいいですか。

188
Veer Shrivastav

データをオブジェクトからJSON文字列ではなくパラメータに変換することが必要だと思います。

Ben Nadelのブログから

デフォルトでは、$ httpサービスはデータをJSONとしてシリアル化し、次にcontent-type「application/json」を付けて送信することによって、発信要求を変換します。 FORM投稿として値を投稿したい場合は、シリアル化アルゴリズムを変更し、content-type "application/x-www-form-urlencoded"でデータを投稿する必要があります。

ここから .

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

更新

AngularJS V1.4で追加された新しいサービスを使用するには、

401
allenhwkim

AngularJSサービスのみを使用するURLエンコード変数

AngularJS 1.4以降では、2つのサービスがPOST要求のデータをURLエンコードするプロセスを処理できるため、transformRequestを使用してデータを操作したり、jQueryのような外部依存関係を使用したりする必要がなくなります。

  1. $httpParamSerializerJQLike - jQueryに触発されたシリアライザ .param()推奨

  2. $httpParamSerializer - GETリクエストのためにAngular自身が使用するシリアライザ

使用例

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

より詳細なPlunkerデモを見る


$httpParamSerializerJQLike$httpParamSerializerはどう違うのですか

一般的に、複雑なデータ構造に関しては、$httpParamSerializer$httpParamSerializerJQLikeよりも「伝統的な」URLエンコード形式を使用しないようです。

例えば(角括弧のパーセントエンコードを無視します):

配列のエンコーディング

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

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

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

オブジェクトのエンコーディング

{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
136
Boaz

これらはすべてやり過ぎるように見えます(または動作しません)。

$http.post(loginUrl, "userName=" + encodeURIComponent(email) +
                     "&password=" + encodeURIComponent(password) +
                     "&grant_type=password"
).success(function (data) {
56
Serj Sagan

問題はJSON文字列形式です。データには単純なURL文字列を使用できます。

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

これがあるべき方法です(そしてバックエンドの変更はしないでください。フロントスタックがapplication/x-www-form-urlencodedをサポートしていない場合は、絶対にしないでください)。

$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では魅力のように動作します

皆さん、アドバイスをください。

  • $httpを扱うときはpromise .then(success, error)を使います。.sucess.errorコールバックは忘れてください(廃止予定のため)

  • Angularjsサイトから here "コールバックパラメータの値を指定するためのプレースホルダとしてJSON_CALLBACK文字列を使用できなくなりました。"

データモデルがユーザー名とパスワードだけでなく、もっと複雑な場合でも、それを実行できます(上記のとおり)。

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

encodeURIComponentのための文書は見つけることができます ここ

3

フォームの場合は、ヘッダーを次のように変更してみてください。

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

それがフォームでも単純なJSONでもない場合は、このヘッダーを試してください。

headers[ "Content-type" ] = "application/json";
2
V31
$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);
});
1
user8483090

$ http docsからこれは動作するはずです..

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

返事が遅くなりましたが、角度付きのUrlSearchParamsが非常にうまく機能していることがわかりました。パラメータのエンコードにも注意が必要です。

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();
1
vanval

あなたは普通のjavascriptオブジェクトを投稿する必要があります。

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

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

あなたがバックエンドとしてphpを持っているなら、あなたはいくつかのより多くの修正をする必要があるでしょう.. checkout このリンク phpサーバー側を修正するために/

1
harishr

これは私のために働きました。フロントエンドにはAngularを使用し、バックエンドにはlalavel phpを使用します。私のプロジェクトでは、Angular WebはJSONデータを送信してlaravelバックエンドにしています。

これは私の角度コントローラです。

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

});

これは私のphpバックエンドlaravelコントローラです。

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

これは私のlaravelルーティングです

Route::post('httpTest','[email protected]');

ブラウザでの結果は

ステータス200
data JSON_CALLBACK({"ユーザー名": "ビクトリア"、 "パスワード": "パスワード"、 "コールバック": "JSON_CALLBACK"}); httpTesting.js:18ヘッダー関数(c){a ||(a = sc(b));戻り値c?a [K(c)] || null:a}

郵便配達員と呼ばれるクロムの拡張子があります。バックエンドのURLが機能しているかどうかをテストするために使用できます。 https://chrome.google.com/webstore/detail/postman-rest-client/fdmmgilgnpjigdojojpjoooidkmcomcm?hl=ja

うまくいけば、私の答えはあなたを助けるでしょう。

0
meazuri