1

Environment:

Intranet

Client: IE8

Server: JBOSS 4.2.3

AJAX Tech: DWR 2.x

I have a requirement to creat modular javascript that can be easily added to any of our intranet applications with a simple script tag. The goal of the script is to create a common session timeout architecture with user-friendly prompts indicating how much time is remaining before the session times out. All of this has been straightforward (using simple setTimeout calls), but I need to account for AJAX requests initiated by DWR that hit the server, thus extending the actual session. Because I need this to be a modular, non-intrusive design, I cannot modify any code within each of the intranet applications. So after much seraching, I found a script that can intercept AJAX calls from a page in order to capture the event - Extending an ActiveXObject in javascript

It would appear that our browser environment is locked down in such a way that a test on window.XMLHttpRequest returns false. As such, I use the portion of the script pertaining to the ActiveX version. DWR appears to be using the msxml2.xmlhttp.6.0 version of the control.

My problem appears to be occuring at this line (between steps 3.4 and 3.5)...

batch.req.setRequestHeader("Content-Type", "text/plain"); //@TODO

within this section of the code within the DWR-generated engine.js file...

try {
    alert("Step 1 - engine.js - before open; batch.req = " + batch.req);
    batch.req.open(batch.httpMethod, request.url, batch.async);
    alert("Step 3 - engine.js - after open; batch.req = " + batch.req);
    try {
      for (prop in batch.headers) {
        var value = batch.headers[prop];
        if (typeof value == "string") {
          batch.req.setRequestHeader(prop, value);
        }
      }
      if (!batch.headers["Content-Type"]) {
        alert("Step 3.4 - engine.js - inside of 'if (!batch.headers[\"Content-Type\"])'; before setRequestHeader call; batch.req = " + batch.req);
        batch.req.setRequestHeader("Content-Type", "text/plain"); //@TODO
        alert("Step 3.5 - engine.js - inside of 'if (!batch.headers[\"Content-Type\"])'; after setRequestHeader call; batch.req = " + batch.req);
      }
    }
    catch (ex) {
      dwr.engine._handleWarning(batch, ex);
    }
    alert("Step 4 - engine.js - before send; batch.req = " + batch.req);
    batch.req.send(request.body);
    alert("Step 5 - engine.js - after send; batch.req = " + batch.req);

Note that "batch.req" is essentially "new ActiveXObject('msxml2.xmlhttp.6.0');"

Here is what is intercepted by the "extend an ActiveXObject" script...

Step 2.1 - CommonSessionTimeout.js
intercepted open (POST , /tbcalltracking/dwr/call/plaincall/JDataHelper.getSystemTime.dwr , true , undefined , undefined)

As is, with the script in place to extend the ActiveXObject, the DWR call fails with the message: "'req' is null or not an object". Viewing the server's logs shows no DWR activity. It as if the call to "setRequestHeader" is invalidating the ActiveX XMLHttpRequest object???

If I comment this line out, I can see DWR activity in the server logs, and I can even see the return value in the logs, but it appears the returned value never gets back to the callback function (and subsequently the page). My guess is that it is because the Content-Type header is not set.

So I tried modifying the script referenced in the above link to set the request header there, thinking that because it "intercepts" such calls, that request headers should be defined there. My first attempt was to simply add this line after the call to "open" (I removed the return keyword)...

this._ax.setRequestHeader("Content-Type", "text/plain");

This had no effect. My second attempt was to add this to the script...

o._setRequestHeader = function () {
    alert("Step 2.0 - setting request header...");
    return this._ax.setRequestHeader("Content-Type", "text/plain");
};

This too had no effect.

Again, I cannot modify the DWR-generated "engine.js" file as other developers may come in later and have to rebuild the file should they modify the underlying Java class (add/remove methods or modify method signatures). Most of the DWR return targets are simple fields on a form - nothing too fancy (that is the case here; DWR initiates a request to a Java class/method which calls a web service - the web service returns a couple of values which are parsed and placed into their appropriate fields).

I'm at my wits end here and am hoping SO can help me out. I feel I am really close, but am simply overlooking or not understanding something. Any help would be greatly appreciated.

Community
  • 1
  • 1
Pennstater
  • 83
  • 1
  • 2
  • 11
  • I was able to use a built-in DWR method to get notifications of DWR requests (see below), but I will leave this question open for the time being in case anyone can answer whether either of the setRequestHeader() implementations is correct. `// this is a check to "intercept" any DWR-made "ajax" calls to the server // As a common practice, we test for the existence of the "dwr" and "dwr.engine" objects before calling any of its methods if (dwr && dwr.engine) { dwr.engine.setPostHook(function() { extendSession(true, true); }); }` – Pennstater Oct 03 '12 at 01:50

0 Answers0