Javascript 如何从拦截器返回soapresponse';s的反应

Javascript 如何从拦截器返回soapresponse';s的反应,javascript,angularjs,soap,Javascript,Angularjs,Soap,我正在为AngularJS创建一个SOAP请求拦截器 它看起来像这样: angular.module('myApp') .factory('SoapInterceptor', ['$q', function ($q) { var soapRequest = function (url, SOAPAction, requestEnvelope, callback) { $.soap({ url: url, appendM

我正在为AngularJS创建一个SOAP请求拦截器

它看起来像这样:

angular.module('myApp')

.factory('SoapInterceptor', ['$q', function ($q) {


    var soapRequest = function (url, SOAPAction, requestEnvelope, callback) {
        $.soap({
            url: url,
            appendMethodToURL: false,
            SOAPAction: SOAPAction,
            enableLogging: false,
            data: requestEnvelope,
            success: function (SOAPResponse) { callback(SOAPResponse.toJSON()); },
            error: function (SOAPResponse) { throw new Error(SOAPResponse); }
        });
    }

    return {
        'request': function (config) {
            if (config.data && config.data.isSoap) {
                var deferred = $q.defer();
                soapRequest(config.url, config.data.soapaction, config.data.requestEnvelope, function (data) {
                    angular.extend(data, config);
                    deferred.resolve(data);
                });
                return deferred.promise;
            }
            return config;
        },
        'response': function (response) {
            // I somehow want this returned response to be my soap response
            // which i have got in request but of course it's no use there
            return response;
        }
    }
}]);
app.service('HttpSoap', ['$q', function ($q) {        
    return function (url, SOAPAction, requestEnvelope) {
            var deferred = $q.defer();
            $.soap({
                url: url,
                appendMethodToURL: false,
                SOAPAction: SOAPAction,
                enableLogging: false,
                data: requestEnvelope,
                success: function (SOAPResponse) { deferred.resolve(SOAPResponse.toJSON()); },
                error: function (SOAPResponse) { deferred.reject(SOAPResponse) }
            });
            return deferred.promise;
        }
}]);
app.controller('myController', function ($scope, HttpSoap) {
    // other code here where I assume that you will define  
    // the reqXml variable
    HttpSoap("http://proxy-send.concep.com/service.asmx", "http://new.cl.truelogic.com.au/CampaignsGetList", reqXml)
        .then(function (jsonData) {
            //things went well
        }, function (errorResponse) {
            //something bad happened
        });
});
因此,我可以在数据存储的方法中使用它,如下所示:

var deferred = $q.defer();

$http.post("http://myapi.com/service.asmx",
    {
        isSoap: true,
        requestEnvelope: reqXml,
        soapaction: "http://myapi.com/CampaignsGetList"
    })
    .success(function (data) {
        deferred.resolve(data);
    });

return deferred.promise;
当isSoap为true时,请求会正确地将其传递给我的
soapRequest
,但是我如何传递我得到的响应,让响应函数返回,以便我的消费者能够愉快地使用承诺


非常感谢您的帮助。

如果我正确理解了这一点,那么当请求内容的数据将标志
isSoap
设置为
true
时,您试图做的是覆盖
$http
服务的行为。看看你的代码,你似乎真的想通过使用拦截器来处理
$http
调用

问题是拦截器不应该这样使用,拦截器应该做的是在
http请求发生之前和/或之后处理事情,但它们不应该自己处理
http请求

然而,我认为你想要的是这样的:

angular.module('myApp')

.factory('SoapInterceptor', ['$q', function ($q) {


    var soapRequest = function (url, SOAPAction, requestEnvelope, callback) {
        $.soap({
            url: url,
            appendMethodToURL: false,
            SOAPAction: SOAPAction,
            enableLogging: false,
            data: requestEnvelope,
            success: function (SOAPResponse) { callback(SOAPResponse.toJSON()); },
            error: function (SOAPResponse) { throw new Error(SOAPResponse); }
        });
    }

    return {
        'request': function (config) {
            if (config.data && config.data.isSoap) {
                var deferred = $q.defer();
                soapRequest(config.url, config.data.soapaction, config.data.requestEnvelope, function (data) {
                    angular.extend(data, config);
                    deferred.resolve(data);
                });
                return deferred.promise;
            }
            return config;
        },
        'response': function (response) {
            // I somehow want this returned response to be my soap response
            // which i have got in request but of course it's no use there
            return response;
        }
    }
}]);
app.service('HttpSoap', ['$q', function ($q) {        
    return function (url, SOAPAction, requestEnvelope) {
            var deferred = $q.defer();
            $.soap({
                url: url,
                appendMethodToURL: false,
                SOAPAction: SOAPAction,
                enableLogging: false,
                data: requestEnvelope,
                success: function (SOAPResponse) { deferred.resolve(SOAPResponse.toJSON()); },
                error: function (SOAPResponse) { deferred.reject(SOAPResponse) }
            });
            return deferred.promise;
        }
}]);
app.controller('myController', function ($scope, HttpSoap) {
    // other code here where I assume that you will define  
    // the reqXml variable
    HttpSoap("http://proxy-send.concep.com/service.asmx", "http://new.cl.truelogic.com.au/CampaignsGetList", reqXml)
        .then(function (jsonData) {
            //things went well
        }, function (errorResponse) {
            //something bad happened
        });
});
定义您自己的“HttpSoap服务”,如下所示:

angular.module('myApp')

.factory('SoapInterceptor', ['$q', function ($q) {


    var soapRequest = function (url, SOAPAction, requestEnvelope, callback) {
        $.soap({
            url: url,
            appendMethodToURL: false,
            SOAPAction: SOAPAction,
            enableLogging: false,
            data: requestEnvelope,
            success: function (SOAPResponse) { callback(SOAPResponse.toJSON()); },
            error: function (SOAPResponse) { throw new Error(SOAPResponse); }
        });
    }

    return {
        'request': function (config) {
            if (config.data && config.data.isSoap) {
                var deferred = $q.defer();
                soapRequest(config.url, config.data.soapaction, config.data.requestEnvelope, function (data) {
                    angular.extend(data, config);
                    deferred.resolve(data);
                });
                return deferred.promise;
            }
            return config;
        },
        'response': function (response) {
            // I somehow want this returned response to be my soap response
            // which i have got in request but of course it's no use there
            return response;
        }
    }
}]);
app.service('HttpSoap', ['$q', function ($q) {        
    return function (url, SOAPAction, requestEnvelope) {
            var deferred = $q.defer();
            $.soap({
                url: url,
                appendMethodToURL: false,
                SOAPAction: SOAPAction,
                enableLogging: false,
                data: requestEnvelope,
                success: function (SOAPResponse) { deferred.resolve(SOAPResponse.toJSON()); },
                error: function (SOAPResponse) { deferred.reject(SOAPResponse) }
            });
            return deferred.promise;
        }
}]);
app.controller('myController', function ($scope, HttpSoap) {
    // other code here where I assume that you will define  
    // the reqXml variable
    HttpSoap("http://proxy-send.concep.com/service.asmx", "http://new.cl.truelogic.com.au/CampaignsGetList", reqXml)
        .then(function (jsonData) {
            //things went well
        }, function (errorResponse) {
            //something bad happened
        });
});
然后像这样使用它:

angular.module('myApp')

.factory('SoapInterceptor', ['$q', function ($q) {


    var soapRequest = function (url, SOAPAction, requestEnvelope, callback) {
        $.soap({
            url: url,
            appendMethodToURL: false,
            SOAPAction: SOAPAction,
            enableLogging: false,
            data: requestEnvelope,
            success: function (SOAPResponse) { callback(SOAPResponse.toJSON()); },
            error: function (SOAPResponse) { throw new Error(SOAPResponse); }
        });
    }

    return {
        'request': function (config) {
            if (config.data && config.data.isSoap) {
                var deferred = $q.defer();
                soapRequest(config.url, config.data.soapaction, config.data.requestEnvelope, function (data) {
                    angular.extend(data, config);
                    deferred.resolve(data);
                });
                return deferred.promise;
            }
            return config;
        },
        'response': function (response) {
            // I somehow want this returned response to be my soap response
            // which i have got in request but of course it's no use there
            return response;
        }
    }
}]);
app.service('HttpSoap', ['$q', function ($q) {        
    return function (url, SOAPAction, requestEnvelope) {
            var deferred = $q.defer();
            $.soap({
                url: url,
                appendMethodToURL: false,
                SOAPAction: SOAPAction,
                enableLogging: false,
                data: requestEnvelope,
                success: function (SOAPResponse) { deferred.resolve(SOAPResponse.toJSON()); },
                error: function (SOAPResponse) { deferred.reject(SOAPResponse) }
            });
            return deferred.promise;
        }
}]);
app.controller('myController', function ($scope, HttpSoap) {
    // other code here where I assume that you will define  
    // the reqXml variable
    HttpSoap("http://proxy-send.concep.com/service.asmx", "http://new.cl.truelogic.com.au/CampaignsGetList", reqXml)
        .then(function (jsonData) {
            //things went well
        }, function (errorResponse) {
            //something bad happened
        });
});
我想指出的其他几点:

  • 你在问题的第二段代码中所做的是一种非常常见的不良行为,往往发生在那些开始熟悉承诺的人中间。当我开始学习Angular的时候,我总是喜欢上它

  • 注意,我去掉了
    工厂
    函数中的
    回调
    参数,因为在Angular中使用
    回调
    是个坏主意,所以最好使用
    $q
    承诺


  • 您是否试图使用拦截器自行处理$http调用?你能看一下我的答案并告诉我这里是否有我遗漏的东西吗?谢谢嗨,乔塞普,谢谢你抽出时间。你建议的答案是我的项目现在是如何运作的。但我认为,如果将http调用的这种处理抽象到$http本身后面会更好。之后我的下一步将是在数据类型处理方面做更多的工作,以删除isSoap标志,这样最终我可以给$http一个soap信封和一个操作,它将知道如何处理它。另外,我可以将它发送到github,这样的解决方案并不存在,如果人们可以下载它,那就太好了。然后我想我可以将它打包成一个模块中的服务,人们可以将它包含在他们的项目中