我想添加一些功能来跟踪javascript中对ActiveX对象方法的某些调用。

我通常会这样创建我的activeX对象:
var tconn = new ActiveXObject(“Tconnector”);

每当在tconn和该activeX控件的所有其他实例上调用打开方法时,我都需要记录日志。

我无法修改tconn的原型(prototype),因为它没有一个!

我认为我可以创建一个虚拟ActiveXObject函数,该函数创建一个代理对象以将调用代理到实际的对象。你能帮我吗?

注意:编写直接包装器是毫无疑问的,因为在应用程序中已经有1000次对此activeX的调用。

最佳答案

实际上,您可以覆盖ActiveXObject()

这意味着您可以尝试围绕实际对象构建透明的代理对象,并挂接方法调用。这意味着您必须围绕ActiveX对象具有的每个方法和属性构建一个代理,除非您完全确定没有任何代码可以调用特定的方法或属性。

我为"MSXML2.XMLHTTP"对象构建了一个小的包装。您可能会遇到各种各样的问题,因此请加一点盐:

var ActualActiveXObject = ActiveXObject;

var ActiveXObject = function(progid) {
  var ax = new ActualActiveXObject(progid);

  if (progid.toLowerCase() == "msxml2.xmlhttp") {
    var o = {
      _ax: ax,
      _status: "fake",
      responseText: "",
      responseXml: null,
      readyState: 0,
      status: 0,
      statusText: 0,
      onReadyStateChange: null
      // add the other properties...
    };
    o._onReadyStateChange = function() {
      var self = o;
      return function() {
        self.readyState   = self._ax.readyState;
        self.responseText = self._ax.responseText;
        self.responseXml  = self._ax.responseXml;
        self.status       = self._ax.status;
        self.statusText   = self._ax.statusText;
        if (self.onReadyStateChange) self.onReadyStateChange();
      }
    }();
    o.open = function(bstrMethod, bstrUrl, varAsync, bstrUser, bstrPassword) {
      varAsync = (varAsync !== false);
      this._ax.onReadyStateChange = this._onReadyStateChange
      return this._ax.open(bstrMethod, bstrUrl, varAsync, bstrUser, bstrPassword);
    };
    o.send = function(varBody) {
      return this._ax.send(varBody);
    };
    // add the other methods...
  }
  else {
    var o = ax;
  }

  return o;
}

function Test() {
  var r = new ActiveXObject('Msxml2.XMLHTTP');

  alert(r._status);  // "fake"

  r.onReadyStateChange = function() { alert(this.readyState); };
  r.open("GET", "z.xml");
  r.send();

  alert(r.responseText);
}

免责声明:特别是async / onReadyStateChange处理可能不正确,并且代码也可能有其他问题。正如我所说,这只是一个主意。小心轻放。

P.S.:COM方法和属性名不区分大小写。这个包装器(和所有JavaScript一样)区分大小写。例如,如果您的代码碰巧同时调用了"Send()""send()",则在包装器中还需要一个框架式的“Send()”方法:
o.Send = function() { return this.send.apply(this, arguments); };

09-09 19:45