现在的位置: 首页 > 移动开发> 正文
服务器端API设计之JSONP
2012年04月18日 移动开发 评论数 6 ⁄ 被围观 7,778+

最近设计项目的服务器端API,起初的设想是客户端采用XML的格式发送数据,然后服务器端返回JSON格式的数据,中间的通信过程采用JS的Ajax机制。

项目初步测试也已通过,功能实现上面倒是没有问题,唯一的缺点就是AJax的跨域通信,想了解更多的关于json,jsonp,ajax和跨域通信的知识可以参照下面的网址:

现在准备花一点时间,把基于json通信的代码全部迁移为基于jsonp通信,这样就能彻底解决了跨域通信的问题,也更方便API的编写,做了调查和了解之后,发现其实代码的改动非常小,示例代码如下:

服务器端的代码:
1. 客户端传入的xml文件的解析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
private function parseInputData()
{
    $params = array();
    if ( $_SERVER['REQUEST_METHOD'] === 'POST' )
    {
        $input = trim(file_get_contents('php://input'));
        import("@.ORG.Util");
        $params = xml_to_array($input);
    } else {
        $input = trim($_REQUEST['params']);
        import("@.ORG.Util");
        $params = xml_to_array($input);
   }
   return $params;
}
private function parseInputData()
{
    $params = array();
    if ( $_SERVER['REQUEST_METHOD'] === 'POST' )
    {
        $input = trim(file_get_contents('php://input'));
        import("@.ORG.Util");
        $params = xml_to_array($input);
    } else {
        $input = trim($_REQUEST['params']);
        import("@.ORG.Util");
        $params = xml_to_array($input);
   }
   return $params;
}

2. 给客户端返回json/jsonp格式的处理数据

1
2
3
4
5
6
7
8
9
10
11
if(strtoupper($type)=='JSON') {
   if (isset($_REQUEST['callback'])) {
      // 返回JSONP数据格式到客户端
      header('Content-Type:text/javascript; charset=utf-8');
      exit($_REQUEST['callback'] . '(' . json_encode($result) . ');');
   } else {
     // 返回JSON数据格式到客户端
     header('Content-Type: application/x-json; charset=utf-8');
     exit(json_encode($result));
   }
}
if(strtoupper($type)=='JSON') {
   if (isset($_REQUEST['callback'])) {
      // 返回JSONP数据格式到客户端
      header('Content-Type:text/javascript; charset=utf-8');
      exit($_REQUEST['callback'] . '(' . json_encode($result) . ');');
   } else {
     // 返回JSON数据格式到客户端
     header('Content-Type: application/x-json; charset=utf-8');
     exit(json_encode($result));
   }
}

客户端的代码:

1. 向服务器发送数据请求

注意:注释掉的代码为普通的Ajax的数据请求,返回Json格式的数据,未注释掉的代码则为Jsonp格式的数据请求,可以跨域通信

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
/*
    向服务器发送 POST 请求.
 
    data:   向服务器发送的数据内容
    succcb: 成功时候的回调函数 function(data)
    errcb:  失败时候的回调函数 function(str)
*/
function doPost(data, succcb, errcb)
{
/*   var req = Ext.Ajax.request({
        url: Config.serverapi,
        params: data,
        success: function(response, opts) {
            var str = 'server-side success [' + response.status + '] ' + response.statusText;
            console.log(str);
            try {
               var data = Ext.decode(response.responseText);
               if (data.status == 0) {
                    errcb(data.info);
               } else {
                    succcb(data.data);
               }
            } catch (e) {
                errcb('服务器返回数据格式错误');
            }
        },
       failure: function(response, opts) {
          var str = 'server-side failure [' + response.status + '] ' + response.statusText;
          console.log(str);
          errcb(str);
       }
    });*/
 
var req = Ext.data.JsonP.request({
      url: Config.serverapi,
      params: {
         'params':data
      },
      callbackKey: 'callback',
      success: function(response) {
          console.log('server-side success !');
          console.dir(response);
          try {
             if (response.status == 0) {
                    errcb(response.info);
             } else {
                    succcb(response.data);
             }
          } catch (e) {
              errcb('服务器返回数据格式错误');
          }
      },
      failure: function(response) {
          var str = 'server-side failure [' + response + '] ';
          console.log(str);
          errcb(str);
       }
    });
 
   return req;
}
/*
    向服务器发送 POST 请求.

    data:   向服务器发送的数据内容
    succcb: 成功时候的回调函数 function(data)
    errcb:  失败时候的回调函数 function(str)
*/
function doPost(data, succcb, errcb)
{
/*   var req = Ext.Ajax.request({
        url: Config.serverapi,
        params: data,
        success: function(response, opts) {
            var str = 'server-side success [' + response.status + '] ' + response.statusText;
            console.log(str);
            try {
               var data = Ext.decode(response.responseText);
               if (data.status == 0) {
                    errcb(data.info);
               } else {
                    succcb(data.data);
               }
            } catch (e) {
                errcb('服务器返回数据格式错误');
            }
        },
       failure: function(response, opts) {
          var str = 'server-side failure [' + response.status + '] ' + response.statusText;
          console.log(str);
          errcb(str);
       }
    });*/

var req = Ext.data.JsonP.request({
      url: Config.serverapi,
      params: {
         'params':data
      },
      callbackKey: 'callback',
      success: function(response) {
          console.log('server-side success !');
          console.dir(response);
          try {
             if (response.status == 0) {
                    errcb(response.info);
             } else {
                    succcb(response.data);
             }
          } catch (e) {
              errcb('服务器返回数据格式错误');
          }
      },
      failure: function(response) {
          var str = 'server-side failure [' + response + '] ';
          console.log(str);
          errcb(str);
       }
    });

   return req;
}

总结:看过之后,有木有什么发现,实际从json迁移到jsonp是非常简单的,只不过多了一步将json格式的数据利用jsonp的callback函数做了一层封装,仅此改变而已。

目前有 6 条留言 其中:访客:5 条, 博主:1 条

  1. AVENT : 2012年05月10日01:06:42  -49楼 @回复 回复

    来占个座

  2. 柠檬茶 : 2012年05月09日11:25:16  -48楼 @回复 回复

    文章很不错,博主很用心,不过您的网站速度有些慢,可以使用WDCDN联盟提供的免费CDN加速服务,还支持免备案加速哦。

  3. 连衣裙夏装 : 2012年05月09日02:23:12  -47楼 @回复 回复

    支持博主!

  4. AVENT : 2012年04月20日22:57:37  -46楼 @回复 回复

    你好 来学习下

  5. wikity : 2012年04月19日17:45:50  -45楼 @回复 回复

    你好 问一下 你的整个博客都是放在github上的吗?

    • 润物无声 : 2012年04月19日19:53:04 @回复 回复

      这个目前还不是,仍是基于虚拟主机托管的wordpress博客,下一步可能考虑要迁移到github上面去!

给我留言

留言无头像?


×
腾讯微博