如何从拦截器的响应中返回soapresponse

时间:2014-10-22 19:04:53

标签: javascript angularjs soap

我正在为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;
        }
    }
}]);

所以我可以在数据存储区的方法中使用它,如下所示:

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但是如何传递响应函数返回的响应,以便我的消费者可以愉快地使用该承诺?

感谢任何帮助。

1 个答案:

答案 0 :(得分:1)

如果我理解正确的话,那么当请求内容的数据的标记$http设置为isSoap时,您要尝试覆盖true服务的行为。看看你的代码,你似乎真的希望通过使用拦截器自己处理$http调用。

问题在于拦截器不应该像这样使用,拦截器应该做的是在http request发生之前和/或之后处理事物,但它们不应该处理{{1自己。

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

定义您自己的“HttpSoap服务”,如下所示:

http request

并像这样使用它:

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;
        }
}]);

我想指出的其他一些事情:

  1. 你在第二段代码中所做的事情是"deferred anti-pattern",这是一种非常常见的不良做法,往往会在那些开始熟悉承诺的人中发生。当我开始使用Angular时,我曾经一直都是这样。

  2. 请注意,我删除了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 }); }); 函数中的callback参数,因为在Angular中使用factory是个坏主意,它是更好地使用callback承诺。