Хорошо, это сложный вопрос, но я думаю, что мне здесь не хватает чего-то очень простого.
Цель
Я пытаюсь создать интерфейс для Trac из другого домена, используя JSON-интерфейс XmlRpcPlugin с Trac API . Я использую серверный скрипт PHP в качестве прокси-сервера из-за одинаковой политики происхождения Javascript .
Статус
Похоже, что прокси (в основном) работает, потому что я получаю ответ от Trac в интерфейсе, управляемом jQuery. Однако я всегда получаю этот ответ:
{
"error": {
"message": "JsonProtocolException details : No JSON object could be decoded",
"code": -32700,
"name": "JSONRPCError"
},
"result": null,
"id": null
}
Это две записи в моем журнале Trac, которые соответствуют каждому запросу:
2012-03-05 11:37:55,943 Trac[json_rpc] ERROR: RPC(json) decode error
Traceback (most recent call last):
File "/usr/local/lib/python2.6/dist-packages/TracXMLRPC-1.1.2_r11148-py2.6.egg/tracrpc/json_rpc.py", line 148, in parse_rpc_request
data = json.load(req, cls=TracRpcJSONDecoder)
File "/usr/lib/python2.6/json/__init__.py", line 267, in load
parse_constant=parse_constant, **kw)
File "/usr/lib/python2.6/json/__init__.py", line 318, in loads
return cls(encoding=encoding, **kw).decode(s)
File "/usr/local/lib/python2.6/dist-packages/TracXMLRPC-1.1.2_r11148-py2.6.egg/tracrpc/json_rpc.py", line 99, in decode
obj = json.JSONDecoder.decode(self, obj, *args, **kwargs)
File "/usr/lib/python2.6/json/decoder.py", line 319, in decode
obj, end = self.raw_decode(s, idx=_w(s, 0).end())
File "/usr/lib/python2.6/json/decoder.py", line 338, in raw_decode
raise ValueError("No JSON object could be decoded")
ValueError: No JSON object could be decoded
2012-03-05 11:37:55,943 Trac[web_ui] ERROR: RPC(JSON-RPC) Error
Traceback (most recent call last):
File "/usr/local/lib/python2.6/dist-packages/TracXMLRPC-1.1.2_r11148-py2.6.egg/tracrpc/web_ui.py", line 143, in _rpc_process
rpcreq = req.rpc = protocol.parse_rpc_request(req, content_type)
File "/usr/local/lib/python2.6/dist-packages/TracXMLRPC-1.1.2_r11148-py2.6.egg/tracrpc/json_rpc.py", line 162, in parse_rpc_request
raise JsonProtocolException(e, -32700)
JsonProtocolException: No JSON object could be decoded
Код
Мой код JQuery:
$.ajax({
url: "/ajax/trac_proxy.php",
dataType: "json",
data: {"method": "system.listMethods", "id": 1},
timeout: 5000,
type: 'POST',
success: function(data, status, XHR){
alert(JSON.stringify(data));
}
});
Мой PHP-скрипт (/ajax/trac_proxy.php
- сокращен для ясности):
<?php
$cparams = array(
'http' => array(
'method' => 'POST',
'ignore_errors' => true,
'content' => http_build_query($_POST),
'header' => "Authorization: Basic " . base64_encode($username . ':' . $password) . "\r\n"
. "Content-Type: application/json\r\n"
)
);
$context = stream_context_create($cparams);
$fp = fopen('https://mytracdomain.com/login/jsonrpc', 'rb', false, $context);
echo stream_get_contents($fp);
?>
Результаты отладки
Чтобы увидеть, что PHP получает / делает, я изменил /ajax/trac_proxy.php
на это:
$cparams = array(
'http' => array(
'content' => http_build_query($_POST),
'method' => 'POST',
'ignore_errors' => true,
'header' => "Authorization: Basic " . base64_encode($username . ':' . $password) . "\r\n"
. "Content-Type: application/json\r\n"
)
);
var_dump($_POST);
var_dump(http_build_query($_POST));
var_dump($cparams);
Вот что я получаю обратно:
array(2) {
["method"]=>
string(18) "system.listMethods"
["id"]=>
string(1) "1"
}
string(30) "method=system.listMethods&id=1"
array(1) {
["http"]=>
array(4) {
["content"]=>
string(30) "method=system.listMethods&id=1"
["method"]=>
string(4) "POST"
["ignore_errors"]=>
bool(true)
["header"]=>
string(79) "Authorization: Basic <REMOVED>
Content-Type: application/json
"
}
}
Окружающая среда
- Trac :
Trac 0.11.7
- Python :
Python 2.6
- Веб-сервер :
Apache 2.2.14
- ОС :
Ubuntu 10.04
Что я делаю не так?