Ajax 方式实现的 PHPRPC 2.1 客户端

80酷酷网    80kuku.com

  ajax|客户端

本文给出了 PHPRPC 2.1 协议的 Ajax 客户端实现。该客户端的使用方式与 2.0 版本的使用方式基本上相同。不同点在于如果要调用的远程函数是引用参数传递的话,需要在调用前设置该函数的 ref 属性为 true。该属性表示是否是引用参数传递。该属性默认为 false。推荐在客户端对象的 onready 事件中进行设置。

下面为该客户端的实现代码:

下载: phprpc_ajax_client.js
  1. /* phprpc_ajax_client.js - Ajax PHPRPC Client
  2. *
  3. * Copyright Ma Bingyao <andotujn.edu.cn>
  4. * Version: 2.1
  5. * LastModified: 2006-03-12
  6. * This library is free.  You can redistribute it and/or modify it.
  7. * http://www.coolcode.cn/?p=146
  8. */
  9. /*
  10. * Interfaces:
  11. * phprpc_client.create('rpc');
  12. * rpc.use_service('http://domain.com/phprpc/server.php');
  13. * rpc.method_callback = function(result, args, output) {
  14. *     if (result instanceof phprpc_error) {
  15. *         alert(result.errstr);
  16. *     }
  17. *     else {
  18. *         alert(result);  // or do any other things.
  19. *     }
  20. * }
  21. * ....
  22. * if (rpc.ready) rpc.method();
  23. */
  24. function phprpc_error(errno, errstr) {
  25.     this.errno = errno;
  26.     this.errstr = errstr;
  27. }
  28. function phprpc_client() {
  29.     this.__php = new PHP_Serializer();
  30.     this.__url = '';
  31.     this.__encrypt = false;
  32.     this.encrypt = 0;
  33.     this.async = true;
  34.     this.ready = false;
  35.     this.args = null;
  36.     this.output = "";
  37.     this.use_service = function (url, encrypt) {
  38.         if (typeof(encrypt) == "undefined") {
  39.             encrypt = this.__encrypt;
  40.         }
  41.         if (typeof(this.__name) == "undefined") {
  42.             return false;
  43.         }
  44.         this.__url = url;
  45.         var xmlhttp = this.__create_xmlhttp();
  46.         var __rpc = this;
  47.         if (encrypt === true) {
  48.             xmlhttp.onreadystatechange = function () {
  49.                 if (xmlhttp.readyState == 4) {
  50.                     if (xmlhttp.responseText) {
  51.                         eval(xmlhttp.responseText);
  52.                         if (typeof(phprpc_encrypt) == "undefined") {
  53.                             __rpc.__encrypt = false;
  54.                             __rpc.use_service(__rpc.__url);
  55.                         }
  56.                         else {
  57.                             __rpc.__encrypt = __rpc.__php.unserialize(phprpc_encrypt);
  58.                             __rpc.__encrypt['p'] = dec2num(__rpc.__encrypt['p']);
  59.                             __rpc.__encrypt['g'] = dec2num(__rpc.__encrypt['g']);
  60.                             __rpc.__encrypt['y'] = dec2num(__rpc.__encrypt['y']);
  61.                             __rpc.__encrypt['x'] = rand(127, 1);
  62.                             var key = pow_mod(__rpc.__encrypt['y'],
  63.                                               __rpc.__encrypt['x'],
  64.                                               __rpc.__encrypt['p']);
  65.                             key = num2str(key);
  66.                             for (var i = 0; i < 16 - key.length; i++) {
  67.                                 key = '\0' + key;
  68.                             }
  69.                             __rpc.__encrypt['k'] = key;
  70.                             var encrypt = pow_mod(__rpc.__encrypt['g'],
  71.                                                   __rpc.__encrypt['x'],
  72.                                                   __rpc.__encrypt['p']);
  73.                             __rpc.use_service(__rpc.__url, num2dec(encrypt).replace(/\+/g, '%2B'));
  74.                         }
  75.                     }
  76.                     delete(xmlhttp);
  77.                 }
  78.             }
  79.         }
  80.         else {
  81.             xmlhttp.onreadystatechange = function () {
  82.                 if (xmlhttp.readyState == 4) {
  83.                     if (xmlhttp.responseText) {
  84.                         eval(xmlhttp.responseText);
  85.                         var functions = __rpc.__php.unserialize(phprpc_functions);
  86.                         var func;
  87.                         for (var i = 0; i < functions.length; i++) {
  88.                             func = __rpc.__name + "." + functions[i] + " = function () {\r\n";
  89.                             func += "    this.__call('"  + functions[i] + "', this.__args_to_array(arguments));\r\n";
  90.                             func += "}\r\n";
  91.                             func += __rpc.__name + "." + functions[i] + ".ref = false;\r\n";
  92.                             eval(func);
  93.                         }
  94.                         __rpc.ready = true;
  95.                         if (typeof(__rpc.onready) == "function") {
  96.                             __rpc.onready();
  97.                         }
  98.                     }
  99.                     delete(xmlhttp);
  100.                 }
  101.             }
  102.         }
  103.         xmlhttp.open("get", this.__url + '?phprpc_encrypt=' + encrypt + '&phprpc_encode=false', true);
  104.         xmlhttp.send(null);
  105.     };
  106.     this.__call = function (func, args) {
  107.         var __args = this.__php.serialize(args);
  108.         if ((this.__encrypt !== false) && (this.encrypt > 0)) {
  109.             __args = xxtea_encrypt(__args, this.__encrypt['k']);
  110.         }
  111.         __args = base64encode(__args);
  112.         var request = 'phprpc_func=' + func
  113.                     + '&phprpc_args=' + __args
  114.                     + '&phprpc_encode=false'
  115.                     + '&phprpc_encrypt=' + this.encrypt;
  116.         var ref = eval(this.__name + "." + func + ".ref");
  117.         if (!ref) {
  118.             request += '&phprpc_ref=false';
  119.         }
  120.         var xmlhttp = this.__create_xmlhttp();
  121.         var session = {'args': args, 'ref': ref, 'encrypt': this.encrypt};
  122.         if (this.async) {
  123.             var __rpc = this;
  124.             xmlhttp.onreadystatechange = function () {
  125.                 if (xmlhttp.readyState == 4) {
  126.                     if (xmlhttp.responseText) {
  127.                         __rpc.__get_result(xmlhttp, session);
  128.                         if (typeof(eval(__rpc.__name + "." + func + "_callback")) == "function") {
  129.                             eval(__rpc.__name + "." + func + "_callback(phprpc_result, phprpc_args, phprpc_output);");
  130.                         }
  131.                     }
  132.                     delete(xmlhttp);
  133.                 }
  134.             }
  135.         }
  136.         xmlhttp.open("post", this.__url, this.async);
  137.         xmlhttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
  138.         xmlhttp.send(request.replace(/\+/g, '%2B'));
  139.         if (!this.async) {
  140.             if (xmlhttp.responseText) {
  141.                 this.__get_result(xmlhttp, session);
  142.                 this.output = phprpc_output;
  143.                 this.args = phprpc_args;
  144.                 return phprpc_result;
  145.             }
  146.             else {
  147.                 return new phprpc_error(1, "No data received from server");
  148.             }
  149.             delete(xmlhttp);
  150.         }
  151.     };
  152.     this.__get_result = function (xmlhttp, session) {
  153.         eval(xmlhttp.responseText);
  154.         if (phprpc_errno == 0) {
  155.             if ((this.__encrypt !== false) && (session.encrypt > 0)) {
  156.                 if (session.encrypt > 1) {
  157.                     phprpc_result = xxtea_decrypt(phprpc_result, this.__encrypt['k']);
  158.                 }
  159.                 if (session.ref) {
  160.                     phprpc_args = xxtea_decrypt(phprpc_args, this.__encrypt['k']);
  161.                 }
  162.             }
  163.             phprpc_result = this.__php.unserialize(phprpc_result);
  164.             if (session.ref) {
  165.                 phprpc_args = this.__php.unserialize(phprpc_args);
  166.             }
  167.             else {
  168.                 phprpc_args = this.args;
  169.             }
  170.         }
  171.         else {
  172.             phprpc_result = new phprpc_error(phprpc_errno, phprpc_errstr);
  173.             phprpc_args = null;
  174.         }
  175.     }
  176.     // the function __create_xmlhttp modified from
  177.     // http://webfx.eae.net/dhtml/xmlextras/xmlextras.html and
  178.     // http://www.ugia.cn/?p=85
  179.     this.__create_xmlhttp = function() {
  180.         if (window.XMLHttpRequest) {
  181.             var objXMLHttp = new XMLHttpRequest();
  182.             // some older versions of Moz did not support the readyState property
  183.             // and the onreadystate event so we patch it!
  184.             if (objXMLHttp.readyState == null) {
  185.                 objXMLHttp.readyState = 0;
  186.                 objXMLHttp.addEventListener(
  187.                     "load",
  188.                     function () {
  189.                         objXMLHttp.readyState = 4;
  190.                         if (typeof(objXMLHttp.onreadystatechange) == "function") {
  191.                             objXMLHttp.onreadystatechange();
  192.                         }
  193.                     },
  194.                     false
  195.                 );
  196.             }
  197.             return objXMLHttp;
  198.         }
  199.         else {
  200.             var MSXML = ['MSXML2.XMLHTTP.5.0', 'MSXML2.XMLHTTP.4.0', 'MSXML2.XMLHTTP.3.0', 'MSXML2.XMLHTTP', 'Microsoft.XMLHTTP'];
  201.             for(var n = 0; n < MSXML.length; n ++) {
  202.                 try {
  203.                     return objXMLHttp = new ActiveXObject(MSXML[n]);
  204.                 }
  205.                 catch(e) {}
  206.             }
  207.             throw new Error("Your browser does not support xmlhttp objects");
  208.         }
  209.     };
  210.     this.__args_to_array = function (args) {
  211.         argArray = [];
  212.         for (i = 0; i < args.length; i++) {
  213.             argArray[i] = args[i];
  214.         }
  215.         return argArray;
  216.     }
  217. }
  218. phprpc_client.create = function (name, encrypt) {
  219.     eval(name + ' = new phprpc_client();');
  220.     eval(name + '.__name = "' + name + '";');
  221.     if (encrypt) {
  222.         encrypt = true;
  223.         eval(name + '.__encrypt = ' + encrypt + ';');
  224.     }
  225. }

作者 andot

<

分享到
  • 微信分享
  • 新浪微博
  • QQ好友
  • QQ空间
点击: