php实现ajax中间服务器,php – 如何组织服务器端的ajax脚本

我使用RPC风格的机制来实现我想你想要的.

免责声明:我已经在JS

PHP和JS

Python中成功实现了这个方案,所以它是可行的.但它可能不安全.您必须采取所有适当的验证步骤以确保它是安全的(特别是w.r.t.到代码/ SQL注入和XSS攻击)

我们的想法是拥有一个处理RPC请求的PHP脚本,通过GET和POST接收方法名称及其参数,并将JSON输出回Javascript端.

例如,在客户端:

API.rpc('getItemById', 1532, function(item) { console.log(item); });

会写的

Object(id=1532,name=”foo”,whatever=”bar”)

在控制台上.

我使用的通信协议如下:

>客户端使用发送HTTP请求到RPC处理程序脚本

无论是GET还是POST.限制是“方法”必须

总是在GET中提供,并且所有参数都必须是

URL编码.否则,所有参数都以key = value对的形式给出,并且可以是请求(GET)或有效负载(POST)的一部分

>服务器总是以HTTP 200响应(否则意味着发生了非常讨厌的事情).它仅响应JSON数据.返回的对象至少有2个成员.

>’success’成员总是在那里,并指示调用是否成功 – 即没有抛出异常

>如果成功,’ret’成员包含函数的返回值

>如果抛出异常,’message’成员包含异常消息(我更喜欢在这里发送整个回溯,但这对敏感环境肯定不好)

(1)在javascript方面(假设jQuery,我认为编码,所以这可能是错误的):

API = function() {

this.rpc = function(method, args, callback) {

return $.ajax({

url: 'rpcscript.php?method='+encodeURIComponent(args.method),

data: args,

type: 'post', //only the method name is sent as a GET arg

dataType: 'json'

error: function() {

alert('HTTP error !'); // This is e.g. an HTTP 500, or 404

},

success: function(data) {

if (data.success) {

callback(data.ret);

} else {

alert('Server-side error:\n'+data.message);

}

},

});

}

}

然后,您可以添加快捷功能,例如syncRPC()以执行同步调用等.

(2)在PHP端(略微修改运行代码):

class MyAPI

{

function getItemById($id)

{

// Assuming the $db is a database connection returning e.g. an associative array with the result of the SQL query. Note the (int) typecast to secure the query - all defensive measures should be used as usual.

return $db->query("SELECT * FROM item WHERE id = ".(int)$id.";");

}

}

class RemoteProcedureCall

{

function __construct()

{

$this->api = new MyAPI();

}

function serve()

{

header("Content-Type: application/json; charset=utf-8");

try

{

if (!isset($_GET['method']))

throw new Exception("Invalid parameters");

$methodDesc = array($this->api, $_GET['method']);

if (!method_exists($methodDesc[0], $methodDesc[1]) || !is_callable($methodDesc))

throw new Exception("Invalid parameters");

$method = new ReflectionMethod($methodDesc[0], $methodDesc[1]);

$params = array();

foreach ($method->getParameters() as $param)

{

// The arguments of the method must be passed as $_POST, or $_GET

if (isset($_POST[$param->getName()]))

// OK, arg is in $_POST

$paramSrc = $_POST[$param->getName()];

elseif (!in_array($param->getName(),array('action','method'))

&& isset($_GET[$param->getName()])

&& !isset($paramSrc[$param->getName()]))

// 'action' and 'method' are reserved $_GET arguments. Arguments for the RPC method

// can be any other args in the query string, unless they are already in $_POST.

$paramSrc = $_GET[$param->getName()];

if (!isset($paramSrc))

{

// If the argument has a default value (as specified per the PHP declaration

// of the method), we allow the caller to use it - that is, not sending the

// corresponding parameter.

if ($param->isDefaultValueAvailable())

$p = $param->getDefaultValue();

else

throw new Exception("Invalid parameters");

}

else

{

$p = $paramSrc;

}

$params[$param->getName()] = $p;

unset($paramSrc);

}

$ret = $method->invokeArgs($db, $params);

echo json_encode(array('success' => true, 'ret' => $ret));

}

catch (Exception $e)

{

echo json_encode(array('success' => false, 'message' => $e->getMessage()."\n".$e->getBacktrace()));

}

}

};

$rpc = RemoteProcedureCall();

$rpc->serve();

这里有许多特定于应用程序的假设,包括可能抛出的异常类型,保留关键字等等……

无论如何,我希望这为你的问题提供一个良好的起点.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值