JavaScript получает нулевой ответ или пустой responseXML от Python SimpleXMLRPCServer

Я нашел ответ на этот вопрос. Это решено.

Повествование: я обращаюсь к Python API, набору methodCalls поверх SimpleXMLRPCServer. Сервер отвечает на запрос GET браузера с помощью html-страницы "web_interface.html". HTML-страница - это очень простой сценарий, который отправляет запрос XHR POST с параметрами xml на сервер 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>

Примечание. При нажатии на кнопку появляются диалоговые окна с предупреждениями. В диалоговом окне состояния отображается «200», а в диалоговых окнах «Текст» и «Ответ» - пусто.


| Данные и заголовки Mozilla Inspector |

Необработанные данные 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. Вот что показывает netcat при срабатывании cURL:


| cURL POST Data |

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. Мы уже протестировали GET-запрос к xhr.responseText в том же браузере на том же компьютере. Программа установки использует тот же хост, тот же порт, тот же каталог как для страницы GET, так и для запроса XHR POST XMLRPC.

Что мне не хватает?


person R. Strack    schedule 11.12.2016    source источник
comment
так .. в основном проблема в том, что GET работает, а POST нет - это завиток GET или POST?   -  person Jaromanda X    schedule 11.12.2016
comment
Команда cURL делает и то, и другое. GET (URL) user: pass отправляются как GET, но преобразуются в заголовки аутентификации. Параметры XML отправляются как данные POST с ключом --data. POST работает; это ответ, который не работает. Инспектор показывает, что браузер отправляет данные POST, а сервер отправляет ответ с пустым XML, сообщаемым JavaScript.   -  person R. Strack    schedule 11.12.2016
comment
Вы говорите, что показанная команда curl делает два запроса?   -  person Jaromanda X    schedule 11.12.2016
comment
@JaromandaX cURL принимает параметр URL получения и преобразует имя пользователя и пароль в заголовок базовой аутентификации. Насколько я могу судить, он делает только один запрос. Я только что отредактировал вопрос и вставил данные, которые отправляет cURL, чтобы вы могли видеть заголовки.   -  person R. Strack    schedule 11.12.2016
comment
Authorization: Basic YWRtaW46Z2liYmVyc2g= vs AuthorizationBasic aGVsbG8=:dGVzdA== - совершенно другой заголовок   -  person Jaromanda X    schedule 11.12.2016
comment
@JaromandaX, правильно. Я использовал это раньше безуспешно. Я изменил сценарий для отправки основного заголовка Auth с кредитами в base64. В любом случае это не имеет значения.   -  person R. Strack    schedule 11.12.2016
comment
итак, авторизация не важна?   -  person Jaromanda X    schedule 11.12.2016
comment
на вкладке сети инструментов разработчика ответ пуст?   -  person Jaromanda X    schedule 11.12.2016
comment
интересно, что заголовок ответа сервера включает Content-type: text/html, но содержимое явно XML, а не HTML   -  person Jaromanda X    schedule 11.12.2016
comment
Разница в основных заголовках заключалась в том, что один из них вырезан и вставлен из инспектора консоли, который не сохраняет знаки препинания, и я заменил пароли ненужных паролей в код, который я вставил сюда онлайн. В инспекторе консоли нет ответа от браузера; кроме заголовков и 200 ок. Понятия не имею, что делаю не так. Прочитал десятки статей и испробовал сотню уловок. Я изменил код Python, чтобы отправлять многочисленные заголовки Content-Type, но ни один из них не работает. Ответ на браузер xhr пуст для text / xml, text / html, text / plain, application / xml, yada yada.   -  person R. Strack    schedule 11.12.2016


Ответы (1)


В Python SimpleXMLRPCServer был взломан некоторый код для обработки файлов cookie. Проблема в том, что код не может обрабатывать объекты cookie, когда браузер устанавливает соединение. Этот код выдавал ошибку при каждом вызове. Это мешало серверу отправить текст ответа в браузер. Я узнал об этом после написания фрагмента кода Python для вывода отладочной информации в файл. Я удалил код cookie, а затем XML-ответ был успешно отправлен с сервера в браузер.

Я также обнаружил, что отправка имени пользователя / пароля из оператора XHR Send вызовет ошибку аутентификации с сервера. Сервер ожидает, что учетные данные будут в заголовке POST как Authentication: Basic base64 [btoa (username: password)].

Заголовок типа содержимого не был виновником в этом случае. Теперь для типа содержимого установлено значение 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>
person R. Strack    schedule 11.12.2016