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. 如何在Eclipse中配置Tomcat服务器

    之前使用MyEclipse来开发Web应用,可以在MyEclipse中配置服务器,配置完后,直接运行服务器即可,很方便. 最近切换到Eclipse开发环境,发现使用Tomcat的方式不太一样,因此在此 ...

  2. 基于密度的聚类之Dbscan算法

    一.算法概述 DBSCAN(Density-Based Spatial Clustering of Applications with Noise)是一个比较有代表性的基于密度的聚类算法.与划分和层次 ...

  3. OneAPM 技术公开课第二讲:开启性能为王的架构时代

    「OneAPM 技术公开课」由应用性能管理第一品牌 OneAPM 发起,内容面向 IT 开发和运维人员.云集技术牛人.知名架构师.实践专家共同探讨技术热点.继北京站第一场火爆上演之后,第二场将于9月1 ...

  4. HDU 4509 湫湫系列故事——减肥记II(暴力模拟即可)

    看了题目后,没自己做,直接看别人题解了,这里转一下. 看了之后,突然想起scanf还可以按照自己写的格式输入数据啊,差点连这个都忘记了啊. 注意输入中时间可能有重复的. http://www.cnbl ...

  5. 适合我胃口的angular.js学习资料

    断断续续弄了半年的ANGULAR.JS学习资料,网上下载了N多资料,测试了很多次. 现在只能算是入门,因时间问题,现在要转入其它领域. 如果以后要拾起来,下面这个PDF比较对我胃口. <Angu ...

  6. 2013 Multi-University Training Contest 2 Balls Rearrangement

    先算出lcm(a,b),如果lcm>=n,则直接暴力解决:否则分段,求出0-lcm内的+0-n%lcm内的值. 再就是连续相同的一起计算!! #include<iostream> # ...

  7. [SQL Server系] -- 约束

    什么是约束? 约束(Constraint)是SQL Server中提供的 自动保存数据库完整性 的一种方法,定义了可输入表或表的列中的数据限制条件. SQL Server中共有5中约束 PRIMARY ...

  8. LINQ——语言级集成查询入门指南(1)

    本文主要是对语言级集成查询或简称为LINQ做一个介绍,包括LINQ是什么,不是什么,并对它在语言特性方面做一个简短的回顾,然后举一些使用LINQ的实际例子进行说明. 语言级集成查询是什么? 在我过去写 ...

  9. IE11兼容IE9问题

    注意如果<head>标签里加<meta http-equiv="X-UA-Compatible"content="IE=EmulateIE9" ...

  10. 李洪强iOS开发之OC语言BLOCK和协议

    OC语言BLOCK和协议 一.BOLCK (一)简介 BLOCK是什么? 苹果推荐的类型,效率高,在运行中保存代码.用来封装和保存代码,有点像函数,BLOCK可以在任何时候执行. BOLCK和函数的相 ...