【问题标题】:How to return the soapresponse from interceptor's response如何从拦截器的响应中返回soapresponse
【发布时间】:2014-10-22 19:04:53
【问题描述】:

我正在为 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 为真时,请求正确地将其传递给我的 soapRequest,但我如何才能将我返回的响应传递给响应函数返回,以便我的消费者可以愉快地使用该承诺?

感谢任何帮助。

【问题讨论】:

  • 您是否尝试使用拦截器自己处理 $http 调用?您能否看看我的答案,让我知道这里是否有我遗漏的东西?谢谢!

标签: javascript angularjs soap


【解决方案1】:

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

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

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

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

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

我想指出的其他几件事:

  1. 您在问题的第二个代码中所做的是"deferred anti-pattern",这是一种非常常见的不良做法,往往发生在开始熟悉 Promise 的人中。当我开始使用 Angular 时,我一直为此而堕落。

  2. 请注意,我删除了factory 函数内部的callback 参数,因为在Angular 中使用callbacks 是个坏主意,最好使用@ 987654333@ 承诺。

【讨论】:

  • 您好 Josep,感谢您抽出宝贵时间。您提出的答案是我的项目现在如何运作。但是我认为如果将这种对 http 调用的处理抽象到 $http 本身之后会更好。之后我的下一步是在数据类型处理上做更多工作以删除 isSoap 标志,所以最后我可以给 $http 一个肥皂信封和一个动作,它会知道如何处理它。另外,我可以将它发送到 github,这样的解决方案不存在,如果人们可以下载它会很好。
  • 然后我想我可以把它打包成一个模块内的服务,人们可以将它包含在他们的项目中
猜你喜欢
  • 2021-08-06
  • 2020-06-19
  • 1970-01-01
  • 2013-06-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-27
  • 1970-01-01
相关资源
最近更新 更多