我在下面的javascript文件中遇到问题。
它由第三方提供,仅在IE QuirksMode中使用。
因为我无法控制服务器后端,所以我无法将API更改为JSON而不是SOAP,并完全避免使用完整的脑script脚本。
所以我修复了脚本,因此它也适用于非内联网环境中IE 10/11中的IE标准模式。
当我在这里时,我也尝试为Chrome修复它。
我只剩下一个我无法解决的问题:
在函数GetSOAPResponseEx中,我收到以下错误:
Uncaught NamespaceError: Failed to execute 'evaluate' on 'Document': The string '//ns1:RunLocatorResponse' contains unresolvable namespaces. SOAPAPI.js:64
XMLDocument.selectSingleNode SOAPAPI.js:64
GetSOAPResponseEx SOAPAPI.js:371
loadOrgRoleUserNames AWEMain.aspx:156
但我不知道为什么或如何解决它。
我的预感是
objXmlDoc.setProperty("SelectionNamespaces", 'xmlns:ns1="http://tempuri.org/AWEService/API/WASAPI"');
与
不完全相同 objXmlDoc = objXmlDomParser.parseFromString(szResponse, "text/xml");
objXmlDoc.documentElement.setAttribute("xmlns:ns1", "http://tempuri.org/AWEService/API/WASAPI");
但我不知道问题是setAttribute还是selectSingleNode中的问题。
这是运行selectSingleNode xpath查询的XML文件:
-- Chrome
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:ns1="http://tempuri.org/AWEService/API/WASAPI">
<soapenv:Body>
<ns1:RunLocatorResponse xmlns="urn:RunLocator"
xmlns:ns1="http://tempuri.org/AWEService/API/WASAPI"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ns1:RunLocatorResult>
<ns1:Target>Administrator</ns1:Target>
<ns1:FirstName>Administrator</ns1:FirstName>
<ns1:LastName>Administrator</ns1:LastName>
</ns1:RunLocatorResult>
<ns1:RunLocatorResult>
<ns1:Target>MyFirstName.MyLastName</ns1:Target>
<ns1:FirstName>MyFirstName</ns1:FirstName>
<ns1:LastName>MyLastName</ns1:LastName>
</ns1:RunLocatorResult>
</ns1:RunLocatorResponse>
</soapenv:Body>
</soapenv:Envelope>
这个XML来自IE
-- IE
<?xml version="1.0"?>
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<ns1:RunLocatorResponse xmlns="urn:RunLocator"
xmlns:ns1="http://tempuri.org/AWEService/API/WASAPI"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<ns1:RunLocatorResult>
<ns1:Target>Administrator</ns1:Target>
<ns1:FirstName>Administrator</ns1:FirstName>
<ns1:LastName>Administrator</ns1:LastName>
</ns1:RunLocatorResult>
<ns1:RunLocatorResult>
<ns1:Target>MyFirstName.MyLastName</ns1:Target>
<ns1:FirstName>MyFirstName</ns1:FirstName>
<ns1:LastName>MyLastName</ns1:LastName>
</ns1:RunLocatorResult>
</ns1:RunLocatorResponse>
</soapenv:Body>
</soapenv:Envelope>
这是有问题的文件:
/* File: SOAPAPI.js
Functions that encapsulate a portal SOAP functions
*/
//-------------------------------------------------------------------------
// Global variables specifically for device placement
//-------------------------------------------------------------------------
// Variables used to communicate with the server via SOAP
var objXmlDoc;
var objXmlDomParser;
var objHttp;
var bDocument = false;
var bHttp = false;
var ghttpAsync = true;
/*
// http://richardpianka.com/2011/01/cross-browser-xpath/
if (document.implementation.hasFeature("XPath", "3.0")) {
if (typeof XMLDocument == "undefined") { XMLDocument = Document; }
XMLDocument.prototype.selectNodes = function(cXPathString, xNode) {
if (!xNode) { xNode = this; }
var oNSResolver = this.createNSResolver(this.documentElement)
var aItems = this.evaluate(cXPathString, xNode, oNSResolver, XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null)
var aResult = [];
for (var i = 0; i < aItems.snapshotLength; i++) { aResult[i] = aItems.snapshotItem(i); }
return aResult;
}
XMLDocument.prototype.selectSingleNode = function(cXPathString, xNode) {
if (!xNode) { xNode = this; }
var xItems = this.selectNodes(cXPathString, xNode);
if (xItems.length > 0) { return xItems[0]; }
else { return null; }
}
Element.prototype.selectNodes = function(cXPathString) {
if (this.ownerDocument.selectNodes) { return this.ownerDocument.selectNodes(cXPathString, this); }
else { throw "For XML Elements Only"; }
}
Element.prototype.selectSingleNode = function(cXPathString) {
if (this.ownerDocument.selectSingleNode) { return this.ownerDocument.selectSingleNode(cXPathString, this); }
else { throw "For XML Elements Only"; }
}
}
*/
var isIE = /**@preserve/*@cc_on!@*/false;
if (!isIE) {
// http://doogalbellend.blogspot.ch/2012/04/cross-browser-selectsinglenode-for-xml.html
//function SelectSingleNode(xmlDoc,
XMLDocument.prototype.selectSingleNode = function(elementPath)
{
var xmlDoc = this;
if (xmlDoc.evaluate)
{
var nodes = xmlDoc.evaluate(elementPath, xmlDoc, null, XPathResult.ANY_TYPE, null);
var results = nodes.iterateNext();
return results;
}
else
return xmlDoc.selectSingleNode(elementPath);
}
} // End if (!isIE) {
//-------------------------------------------------------------------------
// Create a generally used DOM document object used to process the result sets
//-------------------------------------------------------------------------
function CreateDOMDocument() {
if (bDocument != false)
return bDocument;
if (window.DOMParser) {
objXmlDomParser = new DOMParser();
bDocument = true;
// objXmlDoc = objXmlDoc.parseFromString(txt, "text/xml");
}
else // Internet Explorer
{
objXmlDoc = new ActiveXObject("Microsoft.XMLDOM");
objXmlDoc.async = false;
bDocument = true;
}
return bDocument;
}
function CreateDOMDocument_old() {
if (bDocument == false) {
// Create the XML Document object
var aszDocumentProgIDs = ["MSXML2.DOMDocument.4.0",
"MSXML2.DOMDocument.3.0",
"MSXML2.DOMDocument",
"MSXML.DOMDocument",
"Microsoft.XmlDom"];
for (var i = 0; !bDocument && i < aszDocumentProgIDs.length; i++) {
try {
objXmlDoc = new ActiveXObject(aszDocumentProgIDs[i]);
bDocument = true;
} catch (objException) {
// error handling elided for clarity
}
}
}
return bDocument;
}
function CreateHTTPSocket() {
// http://stackoverflow.com/questions/2557247/easiest-way-to-retrieve-cross-browser-xmlhttprequest
if (bHttp != false)
return bHttp;
var XMLHttpFactories = [
function() { return new XMLHttpRequest() },
function() { return new ActiveXObject("Msxml3.XMLHTTP") },
function() { return new ActiveXObject("Msxml2.XMLHTTP.4.0") },
function() { return new ActiveXObject("Msxml2.XMLHTTP.3.0") },
function() { return new ActiveXObject("Msxml2.XMLHTTP") },
function() { return new ActiveXObject("Microsoft.XMLHTTP") }
];
for (var i = 0; i < XMLHttpFactories.length; i++) {
try {
objHttp = XMLHttpFactories[i]();
bHttp = true;
}
catch (e) {
continue;
}
break;
}
return bHttp;
}
//-------------------------------------------------------------------------
// Create a generally used HTTP socket object used to communicate with WAS
//-------------------------------------------------------------------------
function CreateHTTPSocket_old() {
if (bHttp == false) {
// Create the XML HTTP object
var aszHttpProgIDs = ["MSXML2.XMLHTTP.4.0",
"MSXML2.XMLHTTP.3.0",
"MSXML2.XMLHTTP",
"Microsoft.XMLHTTP"];
var aszHttpAsyncFlags = [true,
true,
false,
false];
for (var i = 2; !bHttp && i < aszHttpProgIDs.length; i++) {
try {
objHttp = new ActiveXObject(aszHttpProgIDs[i]);
bHttp = true;
ghttpAsync = aszHttpAsyncFlags[i];
} catch (objException) {
// error handling elided for clarity
}
}
}
return bHttp;
}
//-------------------------------------------------------------------------
// Insert the specified search parameters into a SOAP parameter block. The
// block types currently supported are for locate, create, change, or delete
// functions
//-------------------------------------------------------------------------
function SOAPEnvelopeEx(action, formIDParms, formFieldsParms, allowNulls) {
var strEnvelope;
var actionVerb;
var parms;
var allowNullsParm = '';
if ((typeof allowNulls == 'boolean') && (allowNulls == true)) allowNullsParm = ' AllowNulls="yes"';
switch (action) {
case 'Locate':
actionVerb = 'RunLocator';
parms = "<locatorSearchFieldsIdentification>" +
formIDParms +
"</locatorSearchFieldsIdentification>";
break;
case 'CreateNewInstance':
actionVerb = 'CreateNewInstance';
parms = "<formIdenfication>" +
formIDParms +
"</formIdenfication>" +
"<formFieldsIdentification>" +
formFieldsParms +
"</formFieldsIdentification>";
break;
case 'ChangeInstance':
actionVerb = 'ChangeInstance';
parms = "<formFieldsIdentification>" +
formIDParms +
"</formFieldsIdentification>";
break;
case 'DeleteInstance':
actionVerb = 'DeleteInstance';
parms = "<formFieldsIdentification>" +
formIDParms +
"</formFieldsIdentification>";
break;
case 'SetInstanceProperty':
actionVerb = 'SetInstanceProperty';
parms = "<formIDIdentification>" +
formIDParms +
"</formIDIdentification>" +
"<instancePropertyIdentification>" +
formFieldsParms +
"</instancePropertyIdentification>";
break;
default:
alert("Unrecognized parameter in formSoapEnvelope");
}
strEnvelope = "<soap:Envelope xmlns:soap='http://schemas.xmlsoap.org/soap/envelope/' " +
"xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' " +
"xmlns:xsd='http://www.w3.org/2001/XMLSchema'>" +
"<soap:Body><" + actionVerb + " xmlns='http://tempuri.org/AWEService/API/WASAPI'" + allowNullsParm + ">" +
"<userIdentification><WAS_userName>" + g_SOAPUSERID + "</WAS_userName>" +
"<WAS_session>" + g_SOAPTransID + "</WAS_session>" +
"</userIdentification>" +
parms +
"</" + actionVerb + "></soap:Body> </soap:Envelope>";
return strEnvelope;
}
//-------------------------------------------------------------------------
// Use an HTTP socket to pass the SOAP information to WAS. Identify the
// routine that will be driven when the result arrives. Supports locate,
// create, change, or delete functions.
//-------------------------------------------------------------------------
function CallSOAPEx(action, handler, formName, strEnvelope) {
// Must be using IE for this to work
// if (!window.ActiveXObject) return;
if (!CreateDOMDocument()) return;
if (!CreateHTTPSocket()) return;
var functionURL = RemoveSSFromURLPrefix(g_SOAPURL) + "/API/AWEService.asmx?w_v=1&w_s=" + g_SUITE_ID;
var actionVerb;
var parms;
switch (action) {
case 'Locate':
actionVerb = 'RunLocator';
parms = functionURL + "&w_o=" + formName;
break;
case 'CreateNewInstance':
actionVerb = 'CreateNewInstance';
parms = functionURL + "&w_ifn=" + formName;
break;
case 'ChangeInstance':
actionVerb = 'ChangeInstance';
parms = functionURL + "&w_o=" + formName;
break;
case 'DeleteInstance':
actionVerb = 'DeleteInstance';
parms = functionURL + "&w_o=" + formName;
break;
case 'SetInstanceProperty':
actionVerb = 'SetInstanceProperty';
parms = functionURL + "&w_o=" + formName;
break;
default:
alert("Unrecognized parameter in formCallSoap");
}
// Set up the post
objHttp.onreadystatechange = handler;
objHttp.open("post", parms, ghttpAsync);
// http://blogs.msdn.com/b/ie/archive/2012/07/19/xmlhttprequest-responsexml-in-ie10-release-preview.aspx
// !! Important !!
try { objHttp.responseType = 'msxml-document'; } catch (e) { }
objHttp.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
objHttp.setRequestHeader("SOAPAction", "http://tempuri.org/AWEService/API/WASAPI/" + actionVerb);
objHttp.send(strEnvelope);
if (!ghttpAsync)
handler();
}
function RemoveSSFromURLPrefix(urlPrefix) {
if (urlPrefix != null) {
var i = urlPrefix.toUpperCase().lastIndexOf("/SS");
if (i > 1) {
return urlPrefix.substring(0, i);
}
}
return urlPrefix;
}
//-------------------------------------------------------------------------
// Find the multi-instance form Response within the response XML
//-------------------------------------------------------------------------
// also see: https://www9.cor-asp.ch/Wincasa_Portal/menu_com.js
function GetSOAPResponseEx(action) {
if (objHttp.readyState != 4) return null;
// Get the return envelope
var szResponse = objHttp.responseText;
// console.log(szResponse);
if (window.DOMParser) {
// console.log(objXmlDoc);
objXmlDoc = objHttp.responseXML; // Because responseType = 'msxml-document'
try {
objXmlDoc.setProperty("SelectionNamespaces", 'xmlns:ns1="http://tempuri.org/AWEService/API/WASAPI"');
// console.log(objXmlDoc.xml);
}
catch (e) {
// console.log("DomParserException");
// console.log(typeof (objXmlDoc));
// console.log(objXmlDoc.selectSingleNode);
objXmlDoc = objXmlDomParser.parseFromString(szResponse, "text/xml");
objXmlDoc.documentElement.setAttribute("xmlns:ns1", "http://tempuri.org/AWEService/API/WASAPI");
// console.log((new XMLSerializer()).serializeToString(objXmlDoc));
// $(xmlDOM.documentElement).attr("xmlns:xsd", "http://www.w3.org/2001/XMLSchema");
}
}
else
{
objXmlDoc.loadXML(szResponse);
objXmlDoc.setProperty("SelectionNamespaces", 'xmlns:ns1="http://tempuri.org/AWEService/API/WASAPI"');
}
// At this point, the 2 xml's have been logged
/*
console.log("foo");
// Here I get:
// Uncaught NamespaceError: Failed to execute 'evaluate' on 'Document':
// The string '//ns1:RunLocatorResponse' contains unresolvable namespaces. SOAPAPI.js:64
XMLDocument.selectSingleNode
objXmlDoc.selectSingleNode('//ns1:RunLocatorResponse');
console.log("bar");
*/
switch (action) {
case 'Locate':
return objXmlDoc.selectSingleNode('//ns1:RunLocatorResponse');
case 'CreateNewInstance':
return objXmlDoc.selectSingleNode('//ns1:CreateNewInstanceResponse');
case 'ChangeInstance':
return objXmlDoc.selectSingleNode('//ns1:ChangeInstanceResponse');
case 'DeleteInstance':
return objXmlDoc.selectSingleNode('//ns1:DeleteInstanceResponse');
case 'SetInstanceProperty':
return objXmlDoc.selectSingleNode('//ns1:SetInstancePropertyResponse');
default:
alert("Unrecognized parameter in GetSOAPResponseEx");
}
}
答案 0 :(得分:2)
正如错误消息Failed to execute 'evaluate' on 'Document'
所示,使用您或您的库用于使用XPath选择节点的DOM文档对象的evaluate
方法会出现问题。要使用带有//ns1:RunLocatorResponse
前缀的路径表达式,您需要确保evaluate
方法知道如何通过执行此操作来解析该前缀。
xmldoc.evaluate(
'//ns1:RunLocatorResponse',
xmldoc,
function (prefix) {
if (prefix === 'ns1')
return 'http://tempuri.org/AWEService/API/WASAPI';
else
return null;
},
XPathResult.ANY_TYPE,
null
);