How to determine whether a request is Ajax or Normal?
Asked Answered
B

2

12

I want to handle errors differently for AJAX requests vs normal requests.

How do I identify whether a request is AJAX or not in Struts2 actions ?

Berthoud answered 31/1, 2013 at 8:39 Comment(0)
P
29

You should check if the Request Header X-Requested-With is present and equals to XMLHttpRequest.

Note that not all the AJAX requests have this header, for example Struts2 Dojo requests don't send it; if you instead are generating AJAX calls with Struts2-jQuery (or with any other new AJAX framework), it is there.

You can check if it's present by using Firebug's Net module... for example, when you vote on Stack Overflow ;)

To check it from within a Struts2 Action, you need to implement the ServletRequestAware interface, then get the Request and check if that particular header is there like this:

public class MyAction extends ActionSupport implements ServletRequestAware {
   private HttpServletRequest request;

   public void setRequest(HttpServletRequest request) {
      this.request = request;
   }

   public HttpServletRequest getRequest() {
      return this.request;
   }

   public String execute() throws Exception{
      boolean ajax = "XMLHttpRequest".equals(
                      getRequest().getHeader("X-Requested-With"));
      if (ajax)
         log.debug("This is an AJAX request");
      else 
         log.debug("This is an ordinary request");

      return SUCCESS;
   }  
}

Note that you can obtain the request via ActionContext too, without implementing the ServletRequestAware interface, but it is not the recommended way:

HttpServletRequest request = ServletActionContext.getRequest();
Plunk answered 31/1, 2013 at 10:53 Comment(9)
Does this mean using struts2 dojo we do cannot get XMLHttpRequest? Or rather does the above code work for all ajax requests?Berthoud
I've tried in a project of mine that was using Struts2-Dojo, and when sending the AJAX requests, it does not append that specific request header ("X-Requested-With"). It does not append any specific header appearently... so if you are using that, you can do as suggested by the other answer, by adding a parameter by yourself and check that.Plunk
"for example, when you vote on Stack Overflow ;)" For a while it was very difficult to not give into the temptation of testing this with a downvote.Saunderson
@Saunderson it is widely known that it works better with upvotes ;) Jokes apart, do you have real doubts about this answer ?Plunk
@Saunderson So why not upvoting ? For the lulz ?Plunk
That is actually a non-standard header that is being added by some Javascript frameworks, like jQuery. Other framework may use a different header or no header at all.Ssw
@Julien, it is a Common non-standard request field. It's not an RFC standard, it's an Industry standard and, if you've hit a corner case not using it, it doesn't seem to me a good reason to downvote this answer, that will still help the 99% of the people looking for a way to identify an AJAX request. I've also specified that old Dojo doesn't send it (but the new Dojo does), for example, so there's also an implicit disclaimer... I'm not sure what your downvote should mean. Cheers.Plunk
@AndreaLigios I don't agree. If you do the standard XMLHttpRequest(), no such header is added. It really depends on the javascript framework you use (jQuery or other) whether this header is used or not, or some other header.Ssw
@Ssw if you're building your own AJAX code from scratch, then you know how to signal that a request is AJAX (by putting this industry-standard header, or by putting a "foobar" header, or by any other way you'll choose to implement in your code). If, instead, you're using a built-in AJAX system of one among the major JS frameworks, the header is there, it is the right way. I'm not saying this is a documentation, it's just an answer, nevertheless useful for almost everyone, hence not deserving a downvote (ignored, if necessary, but downvoted ?). Thanks for your feedbacks, by the wayPlunk
G
3

The other alternative, which I use is to add the parameter ajax=true to all Ajax url strings and test in my action with an isAjax() method.

Glossography answered 31/1, 2013 at 14:43 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.