Единственный универсальный способ обращения к веб-службам, ступный во всех современных броузерах, - это использование < XMLHttp. Поскольку в Internet Explorer, Firefox, Opera и Safari ре вана поддержка XMLHttp, это лучший из возможных способов ре ции универсального доступа к веб-службам, не зависящий от типа.1 узера. К сожалению, претворить этот способ в жизнь не так-то щ придется создать запрос SOAP вручную и послать его на сервер.; ную же придется потом произвести разбор полученного резул и контролировать появление ошибок.В этой пьесе есть два главных героя: класс XmlHttp ActiveX в реализации от Microsoft и класс XmlHttpRequest, входящий в реализацию броузеров Mozilla, Opera и Safari. Оба они обладают одинаковыми методами и свойствами. Учитывая, что на этой сцене Microsoft появилась раньше, еще до того, как эти объекты стали стандартами, реализация в броузере Mozilla точнее соответствует рекомендациям W3C. В основе классов лежит возможность выполнения запросов HTTP по заданному адресу а Сети. Получатель не обязан присылать ответ в формате XML, формат ответа может быть любым. В случае протокола SOAP обычно выбира¬ется метод отправки данных в виде запроса типа POST, в теле которого • качестве полезной нагрузки находится элемент \n"
+ "\n"
+ "<" + sMethod + " xmlns=\"" + SOAP_ACTION_BASE + "\">\n" + "" + s0p1 + "\n" + "" + s0p2 + "\n" + "\n" + "\n" + "\n"; return sRequest;
}
Функция getRequestO достаточно проста- она всего лишь собирает строку запроса SOAP в соответствующем формате. (Формат строки нежно увидеть, воспользовавшись тестовым полигоном .NET, о кото¬рое мы говорили, когда создавали веб-службу Math.) Строка запроса ЮАР, возвращаемая функцией getRequestO, нужна функции perform-Sjaecif icOperation() для построения полного запроса:
function performSpecificOperation(sMethod, sOpI, s0p2) { oXmlHttp = zXmlHttp.createRequestO; setl)IEnabled(false);
var sRequest = getRequest(sMethod, sOpI, s0p2); var sSoapActionHeader = SOAP_ACTIONJASE + "/" + sMethod; oXmlHttp.openC'POST", SERVICEJJRL, true); oXmlHttp.onreadystatechange = handleResponse;
oXmlHttp.setRequestHeader("Content-Type", "text/xml"); oXmlHttp.setRequestHeader("SOAPAction", sSoapActionHeader); oXmlHttp.send(sRequest);
document.getElementBy!d("txtRequest").value = sRequest;
}
Первым обращением к библиотеке zXml создается объект zXil Как уже говорилось, в Internet Explorer этот объект будет при жать к классу ActiveX, а в броузерах, созданных на базе Мс к классу XmlHttpRequest. Метод ореп() инициализирует запрос, аргумент метода определяет тип запроса POST, во втором пер URL службы, а третий определяет, будет ли запрос выпол в асинхронном режиме или программный код должен ожидать i да ответа на запрос.
В свойство запроса onreadystatechange записывается ссылка на цию, которая будет вызываться при изменении состояния запроса.!
После этого функция performSpecificOperation() добавляет в запрос 1 два заголовка. Первый определяет тип содержимого (text/xml), i рой представляет собой заголовок SOAPAction. Содержимое этого] ловка можно увидеть в тестовой странице веб-службы или в WSDL в виде атрибута soapAction элемента . По редачи запроса его содержимое отображается в левом текстовом i При каждом изменении состояния запроса вызывается функция i leResponseQ:
function handleResponseO {
if (oXmlHttp.readyState == 4) {
setUIEnabled(true);
var oResponseOutput = document.getElementById("txtResponse"); var oResultOutput = document.getElementById("txtResult"); var oXmlResponse = oXmlHttp.responseXML; var sHeaders = oXmlHttp.getAHResponseHeaders(); if (oXmlHttp.status != 200 || !oXmlResponse.xml) {
а1еП:("0шибка доступа к веб-службе.\n" + oXmlHttp.statusText
+ "\пПодробное описание см. в области вывода ответа, var sResponse = (oXmlResponse.xml ? oXmlResponse.xml :
oXmlResponseText); oResponseOutput.value = sHeaders + sResponse; return;
}
oResponseOutput.value = sHeaders + oXmlResponse.xml; var sResult =
oXmlResponse.documentElement.firstChild.firstChild.firstChild.firstChiic.i oResultOutput.value = sResult;
Функция handleResponseQ реагирует на каждое изменение состояния «проса.1 Когда свойство readyState приобретает значение 4, что гово¬рит о завершении выполнения запроса, можно проверить коррект¬ность полученного результата.
Вели свойство oXmlHttp. status не равно 200 или свойство responseXML со-иержит пустое значение, значит, возникла ошибка и перед пользовате¬лем необходимо вывести сообщение об ошибке. Если это ошибка про¬токола SOAP, то соответствующая информация также отображается •области сообщений на странице. В противном случае отображается содержимое свойства responseText. Если же запрос увенчался успехом, текст в формате XML отображается в правой текстовой области.
Жсть целый ряд способов извлечения фактического результата из кор¬ректного ответа, включая XSLT, интерфейс DOM или синтаксический анализ текста. К сожалению, очень немногие из них могут применять¬ся как универсальное средство, не зависящее от типа броузера. Метод, основанный на интерфейсе DOM, построен на постепенном движении но дереву документа и выглядит не очень элегантно, но он обладает тем достоинством, что его можно применить к любым документам XML.