环境:
内联网
客户端:IE8
服务器:JBOSS 4.2.3
AJAX 技术:DWR 2.x
我需要创建模块化 javascript,可以通过简单的脚本标签轻松地将其添加到我们的任何 Intranet 应用程序中。该脚本的目标是创建一个通用的会话超时架构,其中包含用户友好的提示,指示在会话超时之前还剩多少时间。所有这一切都很简单(使用简单的 setTimeout 调用),但我需要考虑 DWR 发起的命中服务器的 AJAX 请求,从而扩展实际会话。因为我需要这是一个模块化的、非侵入式的设计,所以我不能修改每个 Intranet 应用程序中的任何代码。因此,经过大量搜索,我找到了一个可以从页面拦截 AJAX 调用以捕获事件的脚本 -在 javascript 中扩展 ActiveXObject
看起来我们的浏览器环境被锁定,以至于对 window.XMLHttpRequest 的测试返回 false。因此,我使用与 ActiveX 版本有关的脚本部分。DWR 似乎正在使用控件的 msxml2.xmlhttp.6.0 版本。
我的问题似乎出现在这一行(在步骤 3.4 和 3.5 之间)...
batch.req.setRequestHeader("Content-Type", "text/plain"); //@TODO
在 DWR 生成的 engine.js 文件中的这部分代码中......
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);
请注意,“batch.req”本质上是“new ActiveXObject('msxml2.xmlhttp.6.0');”
这是“扩展 ActiveXObject”脚本截获的内容...
Step 2.1 - CommonSessionTimeout.js
intercepted open (POST , /tbcalltracking/dwr/call/plaincall/JDataHelper.getSystemTime.dwr , true , undefined , undefined)
照原样,使用扩展 ActiveXObject 的脚本,DWR 调用失败并显示消息:“'req' 为空或不是对象”。查看服务器的日志显示没有DWR 活动。好像对“setRequestHeader”的调用使 ActiveX XMLHttpRequest 对象无效???
如果我将此行注释掉,我可以在服务器日志中看到 DWR 活动,甚至可以在日志中看到返回值,但似乎返回的值永远不会返回到回调函数(以及随后的页面)。我的猜测是因为没有设置 Content-Type 标头。
所以我尝试修改上面链接中引用的脚本以在那里设置请求标头,认为因为它“拦截”此类调用,所以应该在那里定义请求标头。我的第一次尝试是在调用“open”之后简单地添加这一行(我删除了 return 关键字)......
this._ax.setRequestHeader("Content-Type", "text/plain");
这没有效果。我的第二次尝试是将其添加到脚本中...
o._setRequestHeader = function () {
alert("Step 2.0 - setting request header...");
return this._ax.setRequestHeader("Content-Type", "text/plain");
};
这也没有效果。
同样,我无法修改 DWR 生成的“engine.js”文件,因为其他开发人员可能会在稍后加入,并且如果他们修改底层 Java 类(添加/删除方法或修改方法签名),则必须重新构建文件。大多数 DWR 返回目标都是表单上的简单字段 - 没什么花哨的(这里就是这种情况;DWR 向调用 Web 服务的 Java 类/方法发起请求 - Web 服务返回几个经过解析的值并放入相应的字段中)。
我在这里束手无策,希望可以帮助我。我觉得我真的很接近,但只是忽略或不理解某些东西。任何帮助将不胜感激。