AngularJS - JSON के बजाय अनुरोध पैरामीटर भेजने के लिए $ http.post के लिए कोई रास्ता?


116

मेरा कुछ पुराना कोड है जो jQuery की पोस्ट विधि के माध्यम से AJAX POST अनुरोध कर रहा है और कुछ इस तरह दिखता है:

$.post("/foo/bar", requestData,
    function(responseData)
    {
        //do stuff with response
    }

requestData कुछ मूलभूत स्ट्रिंग गुणों के साथ एक जावास्क्रिप्ट ऑब्जेक्ट है।

मैं कोणीय का उपयोग करने के लिए हमारे सामान को स्थानांतरित करने की प्रक्रिया में हूं, और मैं इस कॉल को $ http.post के साथ बदलना चाहता हूं। मैं निम्नलिखित के साथ आया:

$http.post("/foo/bar", requestData).success(
    function(responseData) {
        //do stuff with response
    }
});

जब मैंने ऐसा किया, तो मुझे सर्वर से 500 त्रुटि प्रतिक्रिया मिली। फायरबग का उपयोग करते हुए, मैंने पाया कि इसने इस तरह अनुरोध शरीर भेजा:

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

सफल jQuery $.postइस तरह से शरीर भेजता है:

param1=value1&param2=value2&param3=value3

जो समापन बिंदु मैं मार रहा हूं वह अनुरोध पैरामीटर की अपेक्षा कर रहा है और JSON का नहीं। तो, मेरा सवाल यह है $http.postकि जावास्क्रिप्ट ऑब्जेक्ट को JSON के बजाय अनुरोध पैरामीटर के रूप में भेजने के लिए बताने के लिए वैसे भी क्या है? हां, मुझे पता है कि मैं ऑब्जेक्ट से स्ट्रिंग का निर्माण कर सकता हूं, लेकिन मैं जानना चाहता हूं कि क्या कोणीय बॉक्स से बाहर के लिए कुछ भी प्रदान करता है।

जवाबों:


140

मुझे लगता है कि paramsconfig पैरामीटर यहाँ काम नहीं करेगा क्योंकि यह शरीर के बजाय यूआरएल को स्ट्रिंग कहते हैं लेकिन (jQuery का उपयोग कर बदलने क्या Infeligo यहाँ का सुझाव दिया एक डिफ़ॉल्ट के वैश्विक ओवरराइड का एक उदाहरण है में जोड़ने के लिए परम परिवर्तित करने के लिए एक उदाहरण के रूप परम स्ट्रिंग के लिए डेटा)।

वैश्विक ट्रांसफ़ॉर्मेंस फ़ंक्शन सेट अप करें:

var app = angular.module('myApp');

app.config(function ($httpProvider) {
    $httpProvider.defaults.transformRequest = function(data){
        if (data === undefined) {
            return data;
        }
        return $.param(data);
    }
});

इस तरह से सभी $ http.post पर कॉल स्वचालित रूप से शरीर को उसी पैरा प्रारूप में बदल देगी जिसका उपयोग jQuery $.postकॉल द्वारा किया जाता है ।

ध्यान दें कि आप सामग्री-प्रकार के हेडर को प्रति कॉल या विश्व स्तर पर इस तरह सेट करना चाहते हैं:

$httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8';

गैर-वैश्विक परिवर्तन प्रति नमूना नमूना:

    var transform = function(data){
        return $.param(data);
    }

    $http.post("/foo/bar", requestData, {
        headers: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'},
        transformRequest: transform
    }).success(function(responseData) {
        //do stuff with response
    });

मैं सोच रहा था कि वहाँ एक ट्रांसफॉर्मर फ़ंक्शन के अलावा कुछ और था, लेकिन ऐसा लगता है कि वहाँ नहीं है। JQuery के परम समारोह के बारे में सिर के लिए धन्यवाद।
dnc253

गैर-वैश्विक प्रति कॉल विधि मेरे लिए अच्छी तरह से काम कर रही है, लेकिन जब विश्व स्तर पर स्थापित करने की कोशिश की जा रही है $httpProvider.defaults, तो यह काम नहीं कर रहा है, इस बारे में कोई सुराग?
डीआरईएफ

1
WRT इसे विश्व स्तर पर कॉन्फ़िगर कर रहा है, मुझे भी समस्या हो रही है। जब मैं यहां दिए गए स्निपेट का उपयोग करके इसे करने की कोशिश करता हूं, तो मुझे एक त्रुटि मिलती Cannot read property "jquery" of undefined.है मैं इसे कैसे ठीक करूं? पुनश्च। प्रति-कॉल परिवर्तन कार्य करते हैं।
kshep92

@ kshep92 क्या हो रहा है कि ट्रांसफॉर्मर फ़ंक्शन को बिना डेटा के अनुरोध पर कॉल किया जा रहा है, इसलिए 'डेटा' अपरिभाषित है। मैंने 'रिटर्न $ .param (डेटा);' से पहले एक गार्ड जोड़ा। इसे ट्रांसफॉर्मर फ़ंक्शन के लिए पहली पंक्ति के रूप में सम्मिलित करें: 'अगर (डेटा = अपरिभाषित) रिटर्न डेटा;' मैंने जो उत्तर दिया है, उसे देखें।
Jere.Jones 15

1
कोणीय 1.4 के रूप में आप jQuery के डॉक्स के
TheRemix

21

यदि कोणीय> = 1.4 का उपयोग किया जाता है , तो यहां मैंने सबसे अच्छा समाधान पाया है जो किसी भी चीज़ या बाहरी चीज़ पर भरोसा नहीं करता है:

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

और फिर आप इसे अपने ऐप में कहीं भी कर सकते हैं:

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

और यह डेटा को सही रूप में क्रमबद्ध करेगा param1=value1&param2=value2और सामग्री-प्रकार हेडर के /requesturlसाथ भेज देगा application/x-www-form-urlencoded; charset=utf-8क्योंकि यह आम तौर पर समाप्ति बिंदुओं पर POST अनुरोधों के साथ अपेक्षित है।


17

AngularJS प्रलेखन से:

params - {ऑब्जेक्ट।} - स्ट्रिंग या ऑब्जेक्ट्स का मैप, जो url के बाद key1 = value1 & key2 = value2 में बदल जाएगा। यदि मान एक स्ट्रिंग नहीं है , तो इसे JSONified किया जाएगा।

इसलिए, मापदंडों के रूप में स्ट्रिंग प्रदान करें। यदि आप ऐसा नहीं चाहते हैं, तो परिवर्तनों का उपयोग करें। फिर से, प्रलेखन से:

इन परिवर्तनों को स्थानीय रूप से ओवरराइड करने के लिए, ट्रांस्फ़ॉर्म फ़ंक्शन को ट्रांसफ़ॉर्मेंस और / या ट्रांसफ़ॉर्मप्रेशन के रूप में निर्दिष्ट करें। डिफ़ॉल्ट रूप से ओवरराइड करने के लिए, $ httpProvider के $ httpProvider.defaults.transformRequest और $ httpProvider.defaults.transformResponse गुणों को ओवरराइड करें।

अधिक जानकारी के लिए प्रलेखन देखें।


मैंने डाक्यूमेंट्स में परमेस को देखा, और ग्लॉपी उल्लेख की तरह, मुझे इसकी आवश्यकता शरीर में है, न कि यूआरएल पर। मैं सोच रहा था कि क्या JSON के बजाय कुछ विकल्प या कुछ ऐसा था जो मैं मापदंडों को करने के लिए याद कर रहा था, लेकिन ऐसा लगता है कि मुझे केवल ट्रांसपरेंसिव संपत्ति का उपयोग करने की आवश्यकता है।
dnc253

15

$.paramअनुरोध में JSON डेटा अनुक्रमित करने के लिए jQuery के फ़ंक्शन का उपयोग करें ।

संक्षेप में, आपके समान कोड का उपयोग करना:

$http.post("/foo/bar",
$.param(requestData),
{
    headers:
    {
        'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'
    }
}
).success(
    function(responseData) {
        //do stuff with response
    }
});

इसका उपयोग करने के लिए, आपको अपने पृष्ठ में jQuery को AngularJS के साथ शामिल करना होगा।


7

ध्यान दें कि कोणीय 1.4 के रूप में, आप jQuery का उपयोग किए बिना प्रपत्र डेटा को क्रमबद्ध कर सकते हैं।

App.js में:

module.run(function($http, $httpParamSerializerJQLike) {
  $http.defaults.transformRequest.unshift($httpParamSerializerJQLike);
});

फिर अपने कंट्रोलर में:

$http({
    method: 'POST',
    url: myUrl',
    headers: {'Content-Type': 'application/x-www-form-urlencoded'},
    data: myData
});

यह उत्तर बहुत अच्छा है। यह कोणीय से पोस्ट के साथ 2 मुख्य समस्याओं को संबोधित करता है। शीर्ष लेख को सही ढंग से सेट किया जाना चाहिए और आपको जसन डेटा को क्रमबद्ध करना होगा। यदि आपको IE8 समर्थन का उपयोग 1.4+ या बाद के संस्करण की आवश्यकता नहीं है।
mbokil

मैंने इसे लागू किया और यह उन मुद्दों को हल करता है जो मैं पोस्ट के साथ कर रहा था, लेकिन यह भी बदलता है कि पैच कैसे काम करता है और प्रतीत होता है कि मैंने $ http.patch () के मेरे सभी उपयोगों को तोड़ दिया है।
माइक फेल्टमैन

5

यह थोड़ा हैक हो सकता है, लेकिन मैंने इस मुद्दे को टाल दिया और सर्वर की तरफ PHP को PHP के POST में बदल दिया:

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

मैंने इस पद्धति का उपयोग किया है, लेकिन मुझे इससे नफरत है; और मुझे यह पता लगाने में बहुत समय लगा कि मुझे इसका उपयोग क्यों करना पड़ा।
मेकोनारियो

जैसे मैंने कहा - यह हैकिंग लगता है। अधिकांश php की तरह;)
टिमोसोलो

5

मुझे कस्टम http प्रमाणीकरण सेट करने में समस्या है क्योंकि $ संसाधन अनुरोध को कैश करते हैं।

यह काम करने के लिए आपको ऐसा करके मौजूदा हेडर को अधिलेखित करना होगा

var transformRequest = function(data, headersGetter){
  var headers = headersGetter();
  headers['Authorization'] = 'WSSE profile="UsernameToken"';
  headers['X-WSSE'] = 'UsernameToken ' + nonce
  headers['Content-Type'] = 'application/json';
};

return $resource(
  url,
    {
    },
    {
      query: {
        method: 'POST',
        url: apiURL + '/profile',
        transformRequest: transformRequest,
        params: {userId: '@userId'}
      },
    }
);

मुझे उम्मीद है कि मैं किसी की मदद करने में सक्षम था। मुझे यह पता लगाने में 3 दिन लगे।


मुझे लगता है कि आपने मुझे 3 दिनों के काम से बचाया है। धन्यवाद!!! मैं अभी भी यह जानने की कोशिश कर रहा हूं कि क्या मैं किसी तरह कॉल रिक्वेस्ट को रोक सकता हूं ताकि मैं हर कॉल के लिए कस्टम हेडर इंजेक्ट कर सकूं।
मार्कोसु

4

डिफ़ॉल्ट हेडर को संशोधित करें:

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

फिर JQuery की $.paramविधि का उपयोग करें:

var payload = $.param({key: value});
$http.post(targetURL, payload);

3
   .controller('pieChartController', ['$scope', '$http', '$httpParamSerializerJQLike', function($scope, $http, $httpParamSerializerJQLike) {
        var data = {
                TimeStamp : "2016-04-25 12:50:00"
        };
        $http({
            method: 'POST',
            url: 'serverutilizationreport',
            headers: {'Content-Type': 'application/x-www-form-urlencoded'},
            data: $httpParamSerializerJQLike(data),
        }).success(function () {});
    }
  ]);

मेरे अनुसार इसका सबसे सरल और सबसे आसान ... कई अन्य तरीके हो सकते हैं
रोहित लूथरा

2

त्वरित समायोजन - आप उन लोगों के लिए जिन्हें ट्रांसफॉर्मर फ़ंक्शन के वैश्विक कॉन्फ़िगरेशन से परेशानी हो रही है, यहाँ Cannot read property 'jquery' of undefinedत्रुटि से छुटकारा पाने के लिए स्निपेट का उपयोग कर रहा हूँ :

$httpProvider.defaults.transformRequest = function(data) {
        return data != undefined ? $.param(data) : null;
    }


0

मैंने इस पूरे के कई बार समस्यात्मक व्यवहार पाया। मैंने इसे एक्सप्रेस (टाइपिंग के बिना) और बॉडीपेयर (डीटी ~ बॉडी-पार्सर टाइपिंग के साथ) से इस्तेमाल किया।

मैंने एक फ़ाइल अपलोड करने की कोशिश नहीं की, बस एक पोस्ट स्ट्रिंग में दिए गए JSON की व्याख्या करने के लिए।

request.bodyबस एक खाली json था ( {})।

बहुत जांच के बाद आखिरकार मेरे लिए यह काम किया:

import { json } from 'body-parser';
...
app.use(json()); <-- should be defined before the first POST handler!

application/jsonक्लाइंट की ओर से अनुरोध स्ट्रिंग में सामग्री प्रकार देना भी महत्वपूर्ण हो सकता है ।


मुझे खेद है "और एक काले मुर्गी का बलिदान" -स्टाइल उत्तर के लिए, जो दुर्भाग्य से टाइपस्क्रिप्ट / नोड / कोणीय वातावरण के वर्तमान चरण में सामान्य है।
पीटर - मोनिक

0

AngularJS v1.4.8 + (v1.5.0) के लिए सिंटैक्स

       $http.post(url, data, config)
            .then(
                    function (response) {
                        // success callback
                    },
                    function (response) {
                        // failure callback
                    }
            );

उदाहरण के लिए:

    var url = "http://example.com";

    var data = {
        "param1": "value1",
        "param2": "value2",
        "param3": "value3"
    };

    var config = {
        headers: {
            'Content-Type': "application/json"
        }
    };

    $http.post(url, data, config)
            .then(
                    function (response) {
                        // success callback
                    },
                    function (response) {
                        // failure callback
                    }
            );
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.