最近接到一个手机项目,我决定用ionic + php + mysql来实现。ionic是一个前端框架,主要用于手机端,它融合了html5、css3、angularJS于一体,用起来很顺手。

  开始构建项目框架,既然有了angular,那么restful就是标配,这就像LMAP一样是一个黄金组合,然后用php设计restful,用angular进行对接,这看起来很美好,做起来可是很痛苦啊!大家先看两段代码

(function($) {
  jQuery.post('/tab', { name : 'john' }).success(function(data) {
    // ...
  });
})(jQuery);
var MainCtrl = function($scope, $http) {
  $http.post('/tab', { name : 'john'}).success(function(data) {
    // ...
  });
};

  当你用$_POST['name']接收参数时你会发现jQuery可以而Angular却不行!为什么会这样呢?问题的根源就在于jQuery是把参数处理成字符串发送的,而Angular是把参数处理成JSON对象发送的。具体来说jQuery发送数据使用的请求头是 Content-Type: x-www-form-urlencoded ,他把    { name : 'john' }  serialize 序列化成了 name = john ,而Angular使用的请求头是 Content-Type: application/json ,他把  { name : 'john' } serialize成了 { "name" : "john" } ,而且我顶你个肺类,一些服务器语言本身并不能unserialize,比如php。

  既然搞清楚了原因,那我们就来搞定它:

     //设置请求头
      $httpProvider.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded;charset=utf-8;'
      /**
       * The workhorse; 把对象序列化( x-www-form-urlencoded 形式).
       * @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;
      };
      //重写$http service 的 transformRequest
      $httpProvider.defaults.transformRequest = [function(data){
        return angular.isObject(data) && String(data) !== '[object File]' ? param(data) : data;
      }]

  把上面代码加到

angular.module('starter', []).config(function($httpProvider){

    //...
});

  就可以了。

  参考:http://victorblog.com/2012/12/20/make-angularjs-http-service-behave-like-jquery-ajax/

 

posted on 2014-11-18 15:14  狂流  阅读(433)  评论(0编辑  收藏  举报