跨域SOAP调用(使用XmlHttpRequest)到具有Windows身份验证的Web服务 [英] Cross domain SOAP call (with XmlHttpRequest) to a webservice with windows authentication

查看:112
本文介绍了跨域SOAP调用(使用XmlHttpRequest)到具有Windows身份验证的Web服务的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们有一个.Net webservice,它运行在一台服务器上,一个Web应用程序(javascript)运行在另一台服务器上。 Web服务需要具有Windows身份验证。



我们在CORS Preflight呼叫中继续收到错误401 Unauthorized,该呼叫在跨域webservice呼叫之前。如果我们在与应用程序相同的机器上移动web服务,则调用运行完美。



现在花了四天时间让它运行起来,希望有人可以指点我正确的方向...



PS:添加了一个JSFiddle来演示这个问题。 小提琴示例



这是我们使用的web.config对于网络服务



We have a .Net webservice which runs on one server and a web application (javascript) running on another. The webservice needs to have Windows Authentication.

We keep getting the error 401 Unauthorized on the CORS Preflight call, which preceeds the cross domain webservice call. If we move the webservice on the same machine as the application, the calls run perfectly.

Spent four days now to get it working, hopefully someone here can point me in the right direction...

P.S.: added a JSFiddle which demonstrates the problem. Example in fiddle

Here is the web.config we use for the webservice

<?xml version="1.0" encoding="UTF-8"?>
<configuration>

  <appSettings />
  <connectionStrings />
  <system.web>
    <compilation debug="true" />
    <authentication mode="Windows" />
    <customErrors mode="Off" />
    <webServices>
      <protocols>
        <add name="HttpSoap" />
        <add name="HttpGet" />
        <add name="HttpPost" />
      </protocols>
    </webServices>
	<httpRuntime maxUrlLength="9999" relaxedUrlToFileSystemMapping="true" maxQueryStringLength="2097151" requestValidationMode="2.0"/>
    <pages validateRequest="false" />
  </system.web>
  <system.webServer>
    <defaultDocument>
      <files>
        <remove value="default.aspx" />
        <remove value="Default.asp" />
        <remove value="index.html" />
        <remove value="iisstart.htm" />
        <remove value="index.htm" />
        <remove value="Default.htm" />
        <add value="webservice.asmx" />
      </files>
    </defaultDocument>
        <httpProtocol>
            <customHeaders>
                <add name="Access-Control-Allow-Origin" value="http://domain.nl" />
                <add name="Access-Control-Allow-Credentials" value="true" />
                <add name="Access-Control-Allow-Headers" value="SOAPAction, Content-Type,Authorization" />
                <add name="Access-Control-Allow-Methods" value="GET, POST, OPTIONS" />
            </customHeaders>
        </httpProtocol>
	  <security>
		  <requestFiltering>
			  <requestLimits maxUrl="10999" maxQueryString="9999" />
		  </requestFiltering>
	  </security>
  </system.webServer>
</configuration>





这是我们正在使用的javascript的和平





Here is the peace of javascript we are using

SOAPClientParameters = (function () {
    function SOAPClientParameters() {
        var self = this;

        self.list = new Array();
    }

    SOAPClientParameters.prototype.add = function (name, value) {
        var self = this;

        self.list[name] = value;
        return self;
    };

    SOAPClientParameters.prototype._serialize = function (o) {
        var s = "";
        switch (typeof (o)) {
            case "string":
                s += o; //real code is a little different but includes >
            case "number":
            case "boolean":
                s += o.toString(); break;
            case "object":
                // Date
                if (testNull(o)) { s += ""; }
                else if (typeof o === 'Date') {
                    dateToSqlString(o); // custom external function to create date to string suitable for MSSQL
                }
                else if (typeof o === 'Array') {
                    for (var p in o) {
                        if (!isNaN(p))   // linear array
                        {
                            (/function\s+(\w*)\s*\(/ig).exec(o[p].constructor.toString());
                            var type = RegExp.$1;
                            switch (type) {
                                case "":
                                    type = typeof (o[p]);
                                case "String":
                                    type = "string"; break;
                                case "Number":
                                    type = "int"; break;
                                case "Boolean":
                                    type = "bool"; break;
                                case "Date":
                                    type = "DateTime"; break;
                            }
                            s += "<" + type + ">" + SOAPClientParameters._serialize(o[p]) + "</" + type + ">"
                        }
                        else    // associative array
                            s += "<" + p + ">" + SOAPClientParameters._serialize(o[p]) + "</" + p + ">"
                    }
                }
                else
                    for (var p in o)
                        s += "<" + p + ">" + SOAPClientParameters._serialize(o[p]) + "</" + p + ">";
                break;
            default:
                throw new Error(500, "SOAPClientParameters: type '" + typeof (o) + "' is not supported");
        }
        return s;
    }

    SOAPClientParameters.prototype.toXml = function () {
        var self = this;

        var xml = "";
        for (var p in self.list) {
            if (typeof self.list[p] !== 'function') {
                xml += "<" + p + ">" + self._serialize(self.list[p]) + "</" + p + ">";
            }
        }
        return xml;
    }

    return SOAPClientParameters;
}());


SOAPClient = (function () {
    function SOAPClient(url, async) {
        var self = this;

        self.xmlHttp = null;

        if (window.XMLHttpRequest) {
            self.xmlHttp = new XMLHttpRequest();
            // patch for Moz (some versions)
            if (self.xmlHttp.readyState == null) {
                self.xmlHttp.readyState = 1;
                self.xmlHttp.addEventListener("load",
                                    function () {
                                        self.xmlHttp.readyState = 4;
                                        if (typeof self.xmlHttp.onreadystatechange == "function")
                                            self.xmlHttp.onreadystatechange();
                                    },
                                    false);
            }
            //req.withCredentials = true; // tried this, but didn't work
        } else {
            throw 'This browser is not supported!';
        }

        self.xmlHttp.async = async;
        if (self.xmlHttp !== null) {
            self.xmlHttp.open("POST", url, self.xmlHttp.async);
            self.xmlHttp.url = url;
            self.xmlHttp.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
            self.xmlHttp.onerror = function () { // handle eg. 40x errors
                if (self.xmlHttp.async) {
                    // resend it synchronous and catch the exception
                    var errorClient = new SOAPClient(self.xmlHttp.url, false);
                    var exception = errorClient.invoke(self.xmlHttp.func, self.xmlHttp.parameters, function () { }, function () { });
                    self.xmlHttp.errorCallback(isnull(exception.message, 'Unknown error...'));
                }
            }

            self.xmlHttp.onload = function () { // handle eg. 50x errors
                if ((self.xmlHttp.readyState === 4) && (self.xmlHttp.status !== 200)) {
                    self.xmlHttp.errorCallback(self.xmlHttp.statusText);
                }
            }
        }
    }

    SOAPClient.prototype.result = function (data) {
        return data;
    };

    SOAPClient.prototype.invoke = function (method, parameters, successCallback, errorCallback) {
        var self = this;

        var ns = 'http://domain.com/';
        var sr = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" +
            "<soap:Envelope " +
            "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " +
            "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" " +
            "xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" +
            "<soap:Body>" +
            "<" + method + " xmlns=\"" + ns + "\">" +
            parameters.toXml() +
            "</" + method + "></soap:Body></soap:Envelope>";

        var soapaction = ((ns.lastIndexOf("/") != ns.length - 1) ? ns + "/" : ns) + method;

        self.xmlHttp.function = method;
        self.xmlHttp.parameters = parameters;
        self.xmlHttp.errorCallback = errorCallback;

        self.xmlHttp.setRequestHeader("SOAPAction", soapaction);

        if (self.xmlHttp.async) {
            self.xmlHttp.onreadystatechange = function () {
                if ((self.xmlHttp.readyState == 4) && (self.xmlHttp.status === 200)) {
                    self.onSuccess();
                }
            }
        }

        try {
            self.xmlHttp.send(sr);
            if (!self.xmlHttp.async) {
                self.onSuccess();
            }
        } catch (ex) {
            return ex;
        }
    }

    SOAPClient.prototype.onSuccess = function () {
        var self = this;

        if ((self.xmlHttp.readyState == 4) && (self.xmlHttp.status === 200)) {
            var o = null;
            var responseText = self.xmlHttp.response;

            // do the success callback here
        }
    }

    return SOAPClient;
}());

推荐答案

1;
switch (type){
case
type = typeof (o [p]) ;
case String
type = string; break ;
case Number
type = int; break ;
case \"Boolean\":
type = \"bool\"; break ;
case \"Date\":
type = \"DateTime\"; break ;
}
s += \"<\" + type + \">\" + SOAPClientParameters._serialize(o[p]) + \"</\" + type + \">\"
}
else // associative array
s += \"<\" + p + \">\" + SOAPClientParameters._serialize(o[p]) + \"</\" + p + \">\"
}
}
else
for (var p in o)
s += \"<\" + p + \">\" + SOAPClientParameters._serialize(o[p]) + \"</\" + p + \">\";
break ;
default:
throw new Error(500, \"SOAPClientParameters: type '\" + typeof (o) + \"' is not supported\");
}
return s;
}

SOAPClientParameters.prototype.toXml = function () {
var self = this;

var xml = \"\";
for (var p in self.list) {
if (typeof self.list[p] !== 'function') {
xml += \"<\" + p + \">\" + self._serialize(self.list[p]) + \"</\" + p + \">\";
}
}
return xml;
}

return SOAPClientParameters;
}());


SOAPClient = (function () {
function SOAPClient(url, async) {
var self = this;

self.xmlHttp = null;

if (window.XMLHttpRequest) {
self.xmlHttp = new XMLHttpRequest();
// patch for Moz (some versions)
if (self.xmlHttp.readyState == null) {
self.xmlHttp.readyState = 1;
self.xmlHttp.addEventListener(\"load\",
function () {
self.xmlHttp.readyState = 4;
if (typeof self.xmlHttp.onreadystatechange == \"function\")
self.xmlHttp.onreadystatechange();
},
false);
}
//req.withCredentials = true; // tried this, but didn't work
} else {
throw 'This browser is not supported!';
}

self.xmlHttp.async = async;
if (self.xmlHttp !== null) {
self.xmlHttp.open(\"POST\", url, self.xmlHttp.async);
self.xmlHttp.url = url;
self.xmlHttp.setRequestHeader(\"Content-Type\", \"text/xml; charset=utf-8\");
self.xmlHttp.onerror = function () { // handle eg. 40x errors
if (self.xmlHttp.async) {
// resend it synchronous and catch the exception
var errorClient = new SOAPClient(self.xmlHttp.url, false);
var exception = errorClient.invoke(self.xmlHttp.func, self.xmlHttp.parameters, function () { }, function () { });
self.xmlHttp.errorCallback(isnull(exception.message, 'Unknown error...'));
}
}

self.xmlHttp.onload = function () { // handle eg. 50x errors
if ((self.xmlHttp.readyState === 4) && (self.xmlHttp.status !== 200)) {
self.xmlHttp.errorCallback(self.xmlHttp.statusText);
}
}
}
}

SOAPClient.prototype.result = function (data) {
return data;
};

SOAPClient.prototype.invoke = function (method, parameters, successCallback, errorCallback) {
var self = this;

var ns = 'http://domain.com/';
var sr = \"<?xml version=\\"1.0\\" encoding=\\"utf-8\\"?>\" +
\"<soap:Envelope \" +
\"xmlns:xsi=\\"http://www.w3.org/2001/XMLSchema-instance\\" \" +
\"xmlns:xsd=\\"http://www.w3.org/2001/XMLSchema\\" \" +
\"xmlns:soap=\\"http://schemas.xmlsoap.org/soap/envelope/\\">\" +
\"<soap:Body>\" +
\"<\" + method + \" xmlns=\\"\" + ns + \"\\">\" +
parameters.toXml() +
\"</\" + method + \"></soap:Body></soap:Envelope>\";

var soapaction = ((ns.lastIndexOf(\"/\") != ns.length - 1) ? ns + \"/\" : ns) + method;

self.xmlHttp.function = method;
self.xmlHttp.parameters = parameters;
self.xmlHttp.errorCallback = errorCallback;

self.xmlHttp.setRequestHeader(\"SOAPAction\", soapaction);

if (self.xmlHttp.async) {
self.xmlHttp.onreadystatechange = function () {
if ((self.xmlHttp.readyState == 4) && (self.xmlHttp.status === 200)) {
self.onSuccess();
}
}
}

try {
self.xmlHttp.send(sr);
if (!self.xmlHttp.async) {
self.onSuccess();
}
} catch (ex) {
return ex;
}
}

SOAPClient.prototype.onSuccess = function () {
var self = this;

if ((self.xmlHttp.readyState == 4) && (self.xmlHttp.status === 200)) {
var o = null;
var responseText = self.xmlHttp.response;

// do the success callback here
}
}

return SOAPClient;
}());
1; switch (type) { case "": type = typeof (o[p]); case "String": type = "string"; break; case "Number": type = "int"; break; case "Boolean": type = "bool"; break; case "Date": type = "DateTime"; break; } s += "<" + type + ">" + SOAPClientParameters._serialize(o[p]) + "</" + type + ">" } else // associative array s += "<" + p + ">" + SOAPClientParameters._serialize(o[p]) + "</" + p + ">" } } else for (var p in o) s += "<" + p + ">" + SOAPClientParameters._serialize(o[p]) + "</" + p + ">"; break; default: throw new Error(500, "SOAPClientParameters: type '" + typeof (o) + "' is not supported"); } return s; } SOAPClientParameters.prototype.toXml = function () { var self = this; var xml = ""; for (var p in self.list) { if (typeof self.list[p] !== 'function') { xml += "<" + p + ">" + self._serialize(self.list[p]) + "</" + p + ">"; } } return xml; } return SOAPClientParameters; }()); SOAPClient = (function () { function SOAPClient(url, async) { var self = this; self.xmlHttp = null; if (window.XMLHttpRequest) { self.xmlHttp = new XMLHttpRequest(); // patch for Moz (some versions) if (self.xmlHttp.readyState == null) { self.xmlHttp.readyState = 1; self.xmlHttp.addEventListener("load", function () { self.xmlHttp.readyState = 4; if (typeof self.xmlHttp.onreadystatechange == "function") self.xmlHttp.onreadystatechange(); }, false); } //req.withCredentials = true; // tried this, but didn't work } else { throw 'This browser is not supported!'; } self.xmlHttp.async = async; if (self.xmlHttp !== null) { self.xmlHttp.open("POST", url, self.xmlHttp.async); self.xmlHttp.url = url; self.xmlHttp.setRequestHeader("Content-Type", "text/xml; charset=utf-8"); self.xmlHttp.onerror = function () { // handle eg. 40x errors if (self.xmlHttp.async) { // resend it synchronous and catch the exception var errorClient = new SOAPClient(self.xmlHttp.url, false); var exception = errorClient.invoke(self.xmlHttp.func, self.xmlHttp.parameters, function () { }, function () { }); self.xmlHttp.errorCallback(isnull(exception.message, 'Unknown error...')); } } self.xmlHttp.onload = function () { // handle eg. 50x errors if ((self.xmlHttp.readyState === 4) && (self.xmlHttp.status !== 200)) { self.xmlHttp.errorCallback(self.xmlHttp.statusText); } } } } SOAPClient.prototype.result = function (data) { return data; }; SOAPClient.prototype.invoke = function (method, parameters, successCallback, errorCallback) { var self = this; var ns = 'http://domain.com/'; var sr = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" + "<soap:Envelope " + "xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " + "xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" " + "xmlns:soap=\"http://schemas.xmlsoap.org/soap/envelope/\">" + "<soap:Body>" + "<" + method + " xmlns=\"" + ns + "\">" + parameters.toXml() + "</" + method + "></soap:Body></soap:Envelope>"; var soapaction = ((ns.lastIndexOf("/") != ns.length - 1) ? ns + "/" : ns) + method; self.xmlHttp.function = method; self.xmlHttp.parameters = parameters; self.xmlHttp.errorCallback = errorCallback; self.xmlHttp.setRequestHeader("SOAPAction", soapaction); if (self.xmlHttp.async) { self.xmlHttp.onreadystatechange = function () { if ((self.xmlHttp.readyState == 4) && (self.xmlHttp.status === 200)) { self.onSuccess(); } } } try { self.xmlHttp.send(sr); if (!self.xmlHttp.async) { self.onSuccess(); } } catch (ex) { return ex; } } SOAPClient.prototype.onSuccess = function () { var self = this; if ((self.xmlHttp.readyState == 4) && (self.xmlHttp.status === 200)) { var o = null; var responseText = self.xmlHttp.response; // do the success callback here } } return SOAPClient; }());


这篇关于跨域SOAP调用(使用XmlHttpRequest)到具有Windows身份验证的Web服务的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆