如何在JavaScript中覆盖location.assign或location.replace函数?

时间:2012-02-13 10:24:55

标签: javascript

我正在尝试覆盖location.assign函数,以便我可以确保它设置的URL始终是绝对的。但我似乎无法让它工作:当我使用Xmlhttprequest.open如下时,它工作正常:

var oldOpen;
oldOpen = XMLHttpRequest.prototype.open;

// override the native open()
XMLHttpRequest.prototype.open = function(){

    //Prepend our proxyURL
    arguments[1] = prependURL+arguments[1];

    // call the native open()
    oldOpen.apply(this, arguments);
}

但是对于location.assign这种技术不起作用。这就是我正在尝试的:

var old;
old = window.location.assign.prototype.constructor;

window.location.assign.prototype.constructor = function(){
    console.log('dd');
    console.log(arguments);
            alert('ff');
}

old.apply(this,arguments);

当我运行此操作时(我正在Chrome中进行测试),结果为Uncaught TypeError: Illegal invocation。如何覆盖location.assign以获得我想要的行为?

3 个答案:

答案 0 :(得分:8)

根据规范无法修改assign方法。请参阅WHATWG HTML Living Standard中的The Location Interface

您会注意到为[Unforgeable]接口定义的Location扩展属性。这是在WebIDL中定义的:“它表示属性或操作将以某种方式反映为ECMAScript属性,这意味着其行为无法修改”。请参阅W3C WebIDL编辑器草稿中的[Unforgeable]

我在尝试修改replace接口上定义的[Unforgeable]方法后发现此线程无效。

答案 1 :(得分:1)

区别在于XMLHttpRequest构造函数函数,但location已经构建。

您可以直接覆盖它:

var old_location_replace = location.replace;
location.replace = function(url) {
    // ....
};

我想我会尝试找到一种不同的方法来解决问题,而不是沉溺于环境内置对象的基本操作。例如,我完全不能保证上述内容能够很好地跨浏览器(IE,特别是,通常不会使“主机”功能和对象成为真正的JavaScript函数和对象,这对于工作)。

更好的方法是使用所有代码调用的函数,然后调用location.replacelocation.assign。如果您试图拦截您无法控制的代码中的来电,那显然不会起作用,但您必须非常仔细地考虑这样做是否合适。

答案 2 :(得分:0)

window.location.assign是一个函数 - 您尝试访问的原型是function原型。请尝试以下方法:

var old;
old = window.location.assign;

window.location.assign = function(){
  console.log('dd');
  console.log(arguments);
  alert('ff');
  old.apply(this, arguments);
}