Getting global handler to all AJAX calls in dojo

拥有回忆 提交于 2019-12-22 17:20:46

问题


I need to invoke some common methods before an AJAX call is made and after the AJAX call (before the actual handler method is called) is success. I'm using dojo.aspect to achieve this.

This is my code sample

function makeAjaxCall(){
    dojo.xhrGet({
        url:"sample_url",
        content:{
            test:"value"
        },
        load:function(response){
            //Do some logic here
        },
        error:function(response){
            //handle error
        }
    });

}

Below is the dojo.aspect which I'm using to get a hook to the XHR calls.

define(["dojo/aspect"], function(aspect){
     aspect.after(dojo, "xhr", function(deferred){
        console.log("AJAX AFTER");
        deferred.then(function(response){
            //CALLED AFTER 'load' METHOD IS CALLED.
            console.log("Testing");
        });
     });
    aspect.before(dojo, "xhr", function(method, args){

        console.log("AJAX BEFORE");
    });
});

Now the problem is deferred.then inside aspect.after is called after the "load" function is called. Is it possible to have a method which is called before the actual load method is invoked?


回答1:


The short answer is yes.

First, there are two ways to make ajax calls in Dojo.

  1. dojo/xhr - this is what you have above and this is deprecated in favor of
  2. dojo/request/xhr

The first implementation will call into the second implementation. So I would recommend using aop on dojo/request/xhr.

aspect.around(require.modules['dojo/request/xhr'], 'result', function(originalXhr){
    return function(url, options, returnDeferred){

        var dfd = new Deferred();

        // Logic before making the xhr call

        originalXhr(url, options, returnDeferred)
            .then(function(response) {

                // Logic handling the response but before resolving the deferred.
                dfd.resolve(vm);
                // Logic after resolving the deferred.

            }, function(err){
                // error handling?
                dfd.reject(msgs);

            }, function(update) {
                dfd.progress(update);
        });

        return dfd;
    };
}); 

You can find the complete implementation at https://github.com/cswing/evinceframework/blob/master/evf-web-js/src/dojo/evf/serviceRegistry.js (~ line 111)

USAGE:

require('dojo/xhr/request', function(xhr){
    xhr({...}).then(
        function(response) {
            //handle response
        },
        function(error) {
            //handle error
        }
    );
});

The dojo/xhr code will translate itself to the usage above, so the code you posted should work.




回答2:


If you switch to the new API - dojo/request

Then you could use dojo/request/xhr and dojo/request/notify




回答3:


In Dojo 1.10 there is new API to globally catch state of requests.

notify("error", function(error){
    console.error(error);
    //SyntaxError: Unexpected token < in JSON at position 0(…)
});

But in my case I get errors in html eg. so in error I get "error SyntaxError: Unexpected token < in JSON at position 0(…)"

In previous version there was an access to response object:

topic.subscribe("/dojo/io/error", function(/*dojo.Deferred*/ dfd, /*Object*/ response){   
  if (response.status === 401) {
    window.location.reload();
  }

});

So I figured out that json handler can be customized:

require(["dojo/request/handlers"], function(handlers){

handlers.register("json", function(response){

    if (response.status === 401) {
        window.location.reload();
        return;
    }

    return JSON.parse(response.text || null);
});

});

This way you are able to detect response.errors before JSON.parse throws exception.



来源:https://stackoverflow.com/questions/17141459/getting-global-handler-to-all-ajax-calls-in-dojo

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!