RPCスタイルのメカニズムを使用して、自分が望むものを実現します。 免責事項:私はこのスキームをJS + PHPとJS + Pythonで正常に実装していますので、が有効ですです。しかし、安全ではないかもしれません。あなたはそれが安全な
アイデアは受信方法、RPC要求を処理し、単一のPHPスクリプトを持つことである(コード/ SQLインジェクションやXSS攻撃に対して特にWRT)であることを確認するために、すべての適切な検証手順を実行する必要がありGETとPOSTの両方で名前とその引数を取得し、JSONをJavascript側に出力します。クライアント側で例えば
、:
API.rpc('getItemById', 1532, function(item) { console.log(item); });
が
オブジェクト書きます(ID = 1532、名前= "foo" を、どんな= "バー")
コンソール上の
私が使用する通信プロトコルは以下の通りです:
- クライアントがGETまたはPOSTのいずれか を使用して、RPCハンドラスクリプトにHTTPリクエストを送信します。制限は、 'method'はGETに常に を指定する必要があり、すべての引数はURLエンコード である必要があります。それ以外の場合は、すべての引数がkey = valueのペアとして指定され、要求(GET)またはペイロード(POST)の一部になることがあります。
- サーバーは常にHTTP 200で応答します(そうでないと非常に厄介なことが起こります)。これはJSONデータだけで応答します。返されるオブジェクトには、少なくとも2つのメンバーがあります。
- 「成功」のメンバーが常にある、と呼び出しが成功したかどうかを示す - 例外が
- 成功した場合にスローされなかったこと、つまり、「RET」のメンバーが、例外があれば機能
- の戻り値が含まれています「メッセージ」メンバは、例外メッセージ(私はここでは全体のバックトレースを送信することを好むが、それは確かに敏感な環境のために良いではありません)のjavascript側で
(1)(、jQueryのを想定しが含まれ、スローされました私が思うようにコーディングしているので、これはバグかもしれないY):あなたは、同期呼び出しを実行するためにこのようなsyncRPC()のようなショートカット機能を追加することができ
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);
}
},
});
}
}
など
(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();
など、予約キーワードをスローされる例外の種類を含め、ここで多くのアプリケーション固有の仮定は、私はこれは良いスタートを提供願っています。とにかく
あります...あなたの問題のポイント。
+1、良い質問 – Rijk
動作可能だが堅く、保証はなく、あなたの仕事は報われる。サービスが明るい観測可能な未来を持っていない限り、おそらくそれを行うべきではありません。 //これらのアイデアを念頭に置いて、次のサービスを作成するとき) – c69