JavaScript从Python SimpleXMLRPCServer

时间:2016-12-11 00:32:24

标签: javascript python xmlhttprequest xml-rpc simplexmlrpcserver

我找到了这个问题的答案。它已经解决了。

叙事:我正在访问一个Python API,一组在SimpleXMLRPCServer之上的methodCalls。服务器使用html页面响应浏览器GET请求," web_interface.html"。 HTML页面是一个非常简单的脚本,它将xml params的XHR POST请求发送到XMLRPC服务器。服务器使用标头但空文档响应XHR POST。服务器使用正确的数据响应cURL。为什么JavaScript没有从服务器获得任何可读数据?

| web_interface.html |

<!DOCTYPE html>
<html>
<head>

<script>

var xrequest = '<?xml version="1.0?"><methodCall><methodName>helloWorld<methodName><params><param><firstWord><string>hello</string><firstWord></param><param><secondWord><string>world</string></secondWord></param></params></methodCall>';

function hello() {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
    if (this.readyState == XMLHttpRequest.DONE) {
        alert(this.responseText);
        alert(this.status);
        alert(this.response);
    }
}
xhr.open('POST', '/', true);
xhr.setRequestHeader("Authorization", "Basic " + "aGVsbG8=" + ":" + "dGVzdA==");
xhr.send(xrequest);    
}    

</script>

</head>
<body>

<div>
  <h2 id="msgoutput">HelloWorld API Test</h2>
  <button type="button" onclick="hello(); return false;">SAY HELLO!</button>
</div>
</body>
</html>

注意:单击该按钮会生成警告对话框。状态对话框显示&#34; 200&#34;而文本和响应对话框为空。

| Mozilla Inspector Data&amp;标题|

POST原始数据:

<?xml version="1.0?"><methodCall><methodName>helloWorld<methodName><params><param><firstWord><string>hello</string><firstWord></param><param><secondWord><string>world</string></secondWord></param></params></methodCall>

响应标头:

Content-Length 332
Content-Type text/html
Date Sat, 10 Dec 2016 23:51:21 GMT
Server BaseHTTP/0.3 Python/2.7.12

请求标题:

Accept text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Encoding gzip, deflate
Accept-Language en-US,en;q=0.5
AuthorizationBasic aGVsbG8=:dGVzdA== (not my actual creds, swapped fakes)
Connection keep-alive
Content-Length 218
Content-Type text/plain;charset=UTF-8
DNT1
Hostlocalhost:8442
Referer http://localhost:8442/
User-Agent Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:50.0) Gecko/20100101 Firefox/50.0

|使用cURL |

进行测试
:~$ curl -i --data '<?xml version="1.0"?><methodCall><methodName>helloWorld</methodName><params><param><firstWord><string>hello</string></firstWord></param><param><secondWord><string>world</string></secondWord></param></params></methodCall>' http://username:password@localhost:8442
HTTP/1.0 200 OK
Server: BaseHTTP/0.3 Python/2.7.12
Date: Sun, 11 Dec 2016 00:00:13 GMT
Content-type: text/html
Content-length: 137

<?xml version='1.0'?>
<methodResponse>
<params>
<param>
<value><string>hello-world</string></value>
</param>
</params>
</methodResponse>

注意:没问题,cURL将XML响应作为文本返回。我将cURL指向netcat套接字,以确切了解它发送到XMLRPC服务器的内容。以下是cURL点击时netcat显示的内容:

| cURL POST数据|

POST / HTTP/1.1
Host: localhost:8442
Authorization: Basic YWRtaW46Z2liYmVyc2g=
User-Agent: curl/7.47.0
Accept: */*
Content-Length: 220
Content-Type: application/x-www-form-urlencoded

<?xml version="1.0"?><methodCall><methodName>helloWorld</methodName><params><param><firstWord><string>hello</string></firstWord></param><param><secondWord><string>world</string></secondWord></param></params></methodCall>

不是CORS。已经在同一台机器上使用相同的浏览器测试了对xhr.responseText的GET请求。安装程序对GET页面和XHR POST XMLRPC请求使用相同的主机,相同的端口,相同的目录。

我错过了什么?

1 个答案:

答案 0 :(得分:0)

Python SimpleXMLRPCServer将一些代码入侵以处理cookie。问题是,当浏览器建立连接时,代码无法处理cookie对象。此代码在每次调用时都会引发错误。它阻止服务器将响应文本发送到浏览器。在编写Python片段以将调试信息输出到文件后,我学到了这一点。我删除了cookie代码,然后响应XML已成功从服务器发送到浏览器。

我还发现从XHR Send语句发送用户名/密码会从服务器引发身份验证错误。服务器期望凭证在POST标头中作为身份验证:基本base64 [btoa(用户名:密码)]。

在这种情况下,内容类型标题不是罪魁祸首。现在,content-type在客户端和服务器上都设置为text / xml。

以下是修改后的JavaScript代码:

<!DOCTYPE html>
<html>
<head>

<script>

var xrequest = '<?xml version="1.0"?><methodCall><methodName>helloWorld</methodName><params><param><firstWord><string>hello</string></firstWord></param><param><secondWord><string>world</string></secondWord></param></params></methodCall>';

function hello() {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function() {
    if (this.readyState == XMLHttpRequest.DONE) {

    }
}
xhr.open("POST", "/", true);
xhr.setRequestHeader("Authorization", "Basic " + btoa("admin" + ":" + "1234"));
xhr.setRequestHeader("Content-Type", "text/xml")
xhr.send(xrequest);    
}    

</script>

</head>
<body>

<div>
  <h2 id="msgoutput">HelloWorld API Test</h2>
  <button type="button" onclick="hello(); return false;">SAY HELLO!</button>
</div>
</body>
</html>