如何代理window.location

问题描述 投票:0回答:1

原本我们只支持浏览器路由,所以我们的代码中有很多代码是通过直接操作window.location来进行路由跳转的,现在我们增加了使用内存路由的嵌入模式,在这个场景中,直接操作window.location到使浏览器的地址改变不再是我们期望的行为。我们希望在不修改代码的情况下使用它。我们希望以嵌入模式重写window.location,而不需要修改代码中的大量调用。

我目前使用的代码如下:

export const proxyLocation = (location: Location) => {
    const newLocation = {
        get pathname() {
            return location.pathname;
        },
        set pathname(value) {
            push(value);
        },
        get href() {
            return patchUrl(location.pathname + location.search);
        },
        set href(value) {
            push(value);
        },
        get origin() {
            return backendServer.url;
        },
        get search() {
            return location.search;
        },
        replace: function (url) {
            replace(url);
        },
        reload: function () {
            replace(window.location.href);
        },
    };

    Object.defineProperty(window, 'location', {
        value: newLocation,
        writable: false,
        configurable: true,
        enumerable: true,
    });
}

但是这段代码运行时会报错:

TypeError:无法重新定义属性:位置 在Function.defineProperty()

这个问题有解决办法吗?

javascript typescript proxy defineproperty
1个回答
0
投票

如果您可以在构建时或使用脚本自动向 JS 文件添加页眉和页脚,您可以定义本地

window
变量,该变量可以是
Proxy
globalThis
。这样你就可以覆盖任何你想要的东西。代理可以是全局变量之前包含的一些全局变量,例如:

请注意,代码应包装到 IIFE 或块中

globalThis._$windowProxy = new Proxy(globalThis, {
  get(window, prop){
    if(prop === 'location') return newLocation;
    return Reflect(...arguments);
  }
});

const newLocation = {
    get pathname() {
        return location.pathname;
    },
    set pathname(value) {
        push(value);
    },
    get href() {
        return patchUrl(location.pathname + location.search);
    },
    set href(value) {
        push(value);
    },
    get origin() {
        return backendServer.url;
    },
    get search() {
        console.log('search');
        return location.search;
    },
    replace: function (url) {
        replace(url);
    },
    reload: function () {
        replace(window.location.href);
    },
};

// the header
(() => {
const window = globalThis._$windowProxy;
const location = window.location


// the code
location.search;
window.location.search;

// the footer
})();
<script type="module">


</script>

© www.soinside.com 2019 - 2024. All rights reserved.