There is much confusion among newcomers to AngularJS as to why the $http service shorthand functions ($http.post(), etc.) don’t appear to be swappable with the jQuery equivalents (jQuery.post(), etc.) even though the respective manuals imply identical usage. That is, if your jQuery code looked like this before:

(function($) {
jQuery.post('/endpoint', { foo: 'bar' }).success(function(response) {
// ...
});
})(jQuery);

You may find that the following doesn’t exactly work for you with AngularJS out of the box:

var MainCtrl = function($scope, $http) {
$http.post('/endpoint', { foo: 'bar' }).success(function(response) {
// ...
});
};

The problem you may encounter is that your server does not appear to receive the { foo: 'bar' } params from the AngularJS request.

The difference is in how jQuery and AngularJS serialize and transmit the data. Fundamentally, the problem lies with your server language of choice being unable to understand AngularJS’s transmission natively—that’s a darn shame because AngularJS is certainly not doing anything wrong. By default, jQuery transmits data usingContent-Type: x-www-form-urlencoded and the familiar foo=bar&baz=moe serialization. AngularJS, however, transmits data using Content-Type: application/json and { "foo": "bar", "baz": "moe" } JSON serialization, which unfortunately some Web server languages—notably PHP—do not unserialize natively.

Thankfully, the thoughtful AngularJS developers provided hooks into the $http service to let us impose x-www-form-urlencoded on all our transmissions. There are many solutions people have offered thus far on forums and StackOverflow, but they are not ideal because they require you to modify either your server code or your desired usage pattern of $http. Thus, I present to you the best possible solution, which requires you to change neither server nor client code but rather make some minor adjustments to $http‘s behavior in the config of your app’s AngularJS module:

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

Do not use jQuery.param() in place of the above homegrown param() function; it will cause havoc when you try to use AngularJS $resourcebecause jQuery.param() will fire every method on the $resource class passed to it! (This is a feature of jQuery whereby function members of the object to parametrize are called and the return values are used as the parametrized values, but for our typical use case in AngularJS it is detrimental since we typically pass “real” object instances with methods, etc.)

Now you can go forward with using $http.post() and other such methods as you would expect with existing server code that expects x-www-form-urlencodeddata. Here are a few sample frames of the final result for your day-to-day, end-to-end code (i.e. what you hoped and dreamed for):

The HTML template

<div ng-app="MyModule" ng-controller="MainCtrl">
<p ng-show="loading">Loading...</p>
<p ng-hide="loading">Response: {{response}}</p>
</div>

The client code (AngularJS)

var MainCtrl = function($scope, $http) {
$scope.loading = true;
$http.post('/endpoint', { foo: 'bar' }).success(function(response) {
$scope.response = response;
$scope.loading = false;
});
};

The server code (PHP)

<?
header('Content-Type: application/json'); // Ta-da, using $_POST as normal; PHP is able to
// unserialize the AngularJS request no problem
echo json_encode($_POST);
?>

Other notes

So you may wonder now, is it possible for PHP to read the JSON request from stock AngularJS? Why, of course, by reading the input to PHP and JSON decoding it:

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

Obviously the downside to this is that the code is a little less intuitive (we’re used to $_POST, after all), and if your server-side handlers are already written to rely on$_POST, you will now have to change server code. If you have a good framework in place, you can probably effect a global change such that your input reader will transparently detect JSON requests, but I digress.

Thank you for reading. I hope you enjoyed my first POST. (Get it?!)

Make AngularJS $http service behave like jQuery.ajax()(转)的更多相关文章

  1. JQuery+Ajax+Struts2+Hibernate 实现完整的登录注册

    写在最前: 下午有招聘会,不想去,总觉得没有准备好,而且都是一些不对口的公司,可是又静不下心来,就来写个博客. 最近在仿造一个书城的网站:http://www.yousuu.com ,UI直接拿来用, ...

  2. Jquery ajax 学习笔记

    本人的js & jq 一直是菜鸟级别,最近不忙就看了看ajax方面的知识,文中部分内容参考自这里&这里 之前一直用js写ajax现在基于jq实现方便多了~ $.get & $. ...

  3. 实现jquery.ajax及原生的XMLHttpRequest跨域调用WCF服务的方法

    关于ajax跨域调用WCF服务的方法很多,经过我反复的代码测试,认为如下方法是最为简便的,当然也不能说别人的方法是错误的,下面就来上代码,WCF服务定义还是延用上次的,如: namespace Wcf ...

  4. 实现jquery.ajax及原生的XMLHttpRequest调用WCF服务的方法

    废话不多说,直接讲解实现步骤 一.首先我们需定义支持WEB HTTP方法调用的WCF服务契约及实现服务契约类(重点关注各attribute),代码如下: //IAddService.cs namesp ...

  5. Jquery ajax调用webservice总结

    jquery ajax调用webservice(C#)要注意的几个事项: 1.web.config里需要配置2个地方 <httpHandlers>      <remove verb ...

  6. 项目中的一个JQuery ajax实现案例

    /**  * brief 这些代码用于在线制图中 attention author <list of authors> <date> begin modify by  * nu ...

  7. jquery ajax跨域的完美解决方法(jsonp方式)

    ajax跨域请求的问题,JQuery对于Ajax的跨域请求有两类解决方案,不过都是只支持get方式,接下来为大家详细介绍下客户端JQuery.ajax的调用代码     今天在项目中需要做远程数据加载 ...

  8. [经验] - JQuery.Ajax + 跨域 (crossDomain) + POST + JSON + WCF RESTful, 5大陷阱和解决方案

    最近在开发WSS RESTful服务的时候, 碰到了这些个纠结的问题. 在网上查找了半天, 找到n多种解决方案, 但是都是部分的, 要么是没有跨域的情况, 要么是没有post的情况, 要么不是用WCF ...

  9. Jquery Ajax 调用 WebService

    原文:http://www.cnblogs.com/andiki/archive/2010/05/17/1737254.html jquery ajax调用webservice(C#)要注意的几个事项 ...

随机推荐

  1. Hibernate各种主键生成策略与配置详解【附1--<generator class="foreign">】

    1.assigned 主键由外部程序负责生成,在 save() 之前必须指定一个.Hibernate不负责维护主键生成.与Hibernate和底层数据库都无关,可以跨数据库.在存储对象前,必须要使用主 ...

  2. 【POJ】【3537】Crosses and Crosses

    博弈论 相当于放了x的位置,左右4格都不能再放x了,谁无处可放就输. n<=2000 直接枚举后继状态,暴力求SG函数即可. 例: 0000000->x..0000 / .x..000 / ...

  3. 无法从 ajax.googleapis.com 下载问题

    除FQ外的解决办法: 打开目录 C:\Windows\System32\drivers\etc,修改 hosts 文件,添加一行 : 127.0.0.1 ajax.googleapis.com 打开I ...

  4. java后台生成zip打包文件

    /** * * @param zipFile 压缩包文件对象 * @param listKey 压缩的图片物理地址 * @return */ public static boolean package ...

  5. Properties --- C++读配置信息的类(一)

    http://blog.csdn.net/billow_zhang/article/details/4304980 在开发实践中,积累了一些通用的C++ 类库,在此写出来给大家分享.也希望能给出更好的 ...

  6. c++ 虚继承与继承的差异 (转)

    转自:CSDN dqjyong 原文链接:http://blog.csdn.net/dqjyong/article/details/8029527 前面一篇文章,说明了在C++ 虚继承对基类构造函数调 ...

  7. D&F学数据结构系列——红黑树

    红黑树 定义:一棵二叉查找树如果满足下面的红黑性质,则为一棵红黑树: 1)每个结点不是红的就是黑的 2)根结点是黑的 3)每个叶结点是黑的 4)如果一个结点是红的,它的两个儿子都是黑的(即不可能有两个 ...

  8. SQL中的事物【转】

    来源于:http://www.cnblogs.com/zhuifengnianshao/archive/2010/11/24/1886939.html 事务(Transaction)是并发控制的单位, ...

  9. 深入浅出ES6(四):模板字符串

    作者 Jason Orendorff  github主页  https://github.com/jorendorff 反撇号(`)基础知识 ES6引入了一种新型的字符串字面量语法,我们称之为模板字符 ...

  10. POJ1328Radar Installation

    http://poj.org/problem?id=1328 题的大意就是说在海里有小岛,坐标位置会给出,需要岸边的雷达覆盖所有的小岛,但雷达的覆盖范围有限,所以,需要最少的雷达覆盖所有的小岛,但若是 ...