javascript - AngularJS-أي طريقة ل $ http.post لإرسال معلمات الطلب بدلاً من JSON؟




jquery (8)

لديّ بعض الأكواد القديمة التي تقدم طلب AJAX POST عبر طريقة المشاركة في jQuery وتبدو كما يلي:

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

requestData هو مجرد كائن javascript مع بعض خصائص السلسلة الأساسية.

أنا بصدد نقل الأشياء الخاصة بنا لاستخدام Angular ، وأريد استبدال هذه المكالمة بـ $ http.post. لقد توصلت إلى ما يلي:

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

عندما فعلت هذا ، حصلت على استجابة 500 خطأ من الخادم. باستخدام Firebug ، وجدت أن هذا أرسل نص الطلب كما يلي:

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

يرسل jQuery $.post الناجح الجسم على النحو التالي:

param1=value1&param2=value2&param3=value3

نقطة النهاية التي أقوم بتوقعها هي توقع معلمات الطلب وليس JSON. لذا ، سؤالي هو هل هناك على أي حال لإعلام $http.post بإرسال كائن javascript كمعلمات للطلب بدلاً من JSON؟ نعم ، أعلم أنه يمكنني إنشاء السلسلة بنفسي من الكائن ، ولكن أريد أن أعرف ما إذا كان Angular يوفر أي شيء لهذا خارج المربع.


أعتقد أن معلمة config المعلمة لن تعمل هنا لأنها تضيف السلسلة إلى عنوان url بدلاً من الجسم ولكن لإضافة ما اقترح Infeligo هنا مثالاً على التجاوز العالمي للتحول الافتراضي (باستخدام param jQuery كمثال تحويل البيانات إلى سلسلة المعلمة).

إعداد وظيفة التحويل العالميRequest:

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 .

لاحظ أنك قد ترغب أيضًا في تعيين رأس Content-Type لكل مكالمة أو على مستوى العالم على النحو التالي:

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

إذا كنت تستخدم Angular> = 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 كـ param1=value1&param2=value2 وإرسالها إلى /requesturl مع application/x-www-form-urlencoded; charset=utf-8 application/x-www-form-urlencoded; charset=utf-8 رأس Content-Type كما هو متوقع عادةً مع طلبات POST على نقاط النهاية.


تعديل الرؤوس الافتراضية:

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

ثم استخدم طريقة $.param الخاصة بـ JQuery:

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

تعديل سريع - لأولئك الذين يواجهون مشكلة في التهيئة العامة لوظيفة transformRequest ، هنا المقتطف الذي أستخدمه للتخلص من Cannot read property 'jquery' of undefined لخطأ Cannot read property 'jquery' of undefined :

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

لاحظ أنه اعتبارًا من Angular 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
});

لدي مشكلات أيضًا في إعداد مصادقة 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 أيام لمعرفة هذا واحد.


من وثائق AngularJS:

params - {Object.} - خريطة السلاسل أو الأشياء التي سيتم تحويلها إلى key1 = value1 و key2 = value2 بعد عنوان url. إذا كانت القيمة ليست سلسلة ، فسيكون JSONified.

لذلك ، تقديم سلسلة كمعلمات. إذا كنت لا تريد ذلك ، فاستخدم التحويلات. مرة أخرى ، من الوثائق:

لتجاوز هذا التحويل محليًا ، حدد وظائف التحويل كخيار التحويل و / أو transformResponse لكائن التكوين. لتجاوز التحويلات الافتراضية على مستوى العالم ، يجب تجاوز httpProvider.defaults.transformRequest و $ httpProvider.defaults.transformResponse $ httpProvider.

الرجوع إلى documentation لمزيد من التفاصيل.






angularjs