V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
zictos
V2EX  ›  JavaScript

js 如何拦截 location.href,让页面的 location.href 都失效或者可以自定义跳转到其他页面?

  •  
  •   zictos · 2021-01-29 11:08:38 +08:00 · 5942 次点击
    这是一个创建于 1428 天前的主题,其中的信息可能已经有所发展或是发生改变。
    alert()和 window.open()都可以拦截,只需要重新赋值即可,比如添加一行 alert=0,那么所有的 alert 就失效了。甚至可以自定义只拦截包括某些字符串的 alert 对话框,具体可以搜索“js 拦截 alert”。

    html 的 a 标签也可以拦截, 具体可以搜索“js 阻止 a 标签跳转”。

    但是 location.href 是一个属性,只要修改属性就会触发页面跳转,设置为任何值都无法让它失效。并且 href 属性也无法删除。难道没其他办法了呢?或者能不能获取到 location.href 这个事件并拦截,然后再自定义做自己想做的事。
    26 条回复    2021-02-05 18:40:00 +08:00
    cjd6568358
        1
    cjd6568358  
       2021-01-29 11:55:16 +08:00
    Object.defineProperty
    ho121
        2
    ho121  
       2021-01-29 11:59:05 +08:00 via Android
    把 location 干掉?
    KuroNekoFan
        3
    KuroNekoFan  
       2021-01-29 12:00:30 +08:00
    ....为什么要在 very bad practise 的路上渐行渐远呢
    musi
        4
    musi  
       2021-01-29 12:05:10 +08:00
    具体可以搜索“js proxy”
    weixiangzhe
        5
    weixiangzhe  
       2021-01-29 12:05:35 +08:00
    我查一了 proxy,貌似也是不行 https://stackoverflow.com/questions/45965893/how-do-i-apply-get-proxy-on-window-location-in-javascript
    ——————
    关注一下,可以整 就可以写个油猴脚本,在手机上阻止部分网页打开 app 了
    zictos
        6
    zictos  
    OP
       2021-01-29 12:11:55 +08:00
    @weixiangzhe #5 其实我就是想阻止手机上打开 app,比如手机网页打开淘宝一般是用下面的代码:
    window.location.href = 'taobao://m.taobao.com'

    taobao://是淘宝注册的 scheme,所以会打开淘宝,后面的 m.taobao.com 就是要打开的网页地址,如果输入 taobao://detail.tmall.com/item.htm?id=616270509106 就会打开一个天猫的服装商品页面
    zjm947373
        7
    zjm947373  
       2021-01-29 12:15:18 +08:00
    一楼正解
    weixiangzhe
        8
    weixiangzhe  
       2021-01-29 12:17:30 +08:00
    @zictos 😂 , 我之前找了一下,貌似没有整,看看楼下怎么说吧,不过现在还有 universal link, schema 是 https 的
    Quarter
        9
    Quarter  
       2021-01-29 12:49:02 +08:00 via iPhone
    可以重新给 window.location 赋值么,不太清楚😪
    zictos
        10
    zictos  
    OP
       2021-01-29 12:55:07 +08:00
    @Quarter #9 不能, 给 window.location 赋值也是默认会直接跳转, 跟 window.location.href 的效果是一样的。况且如果整个 window.location 都不能用了,对整个网页的影响会比较大
    mxT52CRuqR6o5
        11
    mxT52CRuqR6o5  
       2021-01-29 13:12:27 +08:00
    @zjm947373
    @cjd6568358
    并不行
    Cannot redefine property
    rekulas
        12
    rekulas  
       2021-01-29 13:31:35 +08:00
    干掉也能恢复
    var i = document.createElement('iframe');
    i.style.display = 'none';
    document.body.appendChild(i);
    window.alert = i.contentWindow.alert;

    这只是其中一种手段
    除非你把大部分函数都禁了 不然总有办法
    sleepm
        13
    sleepm  
       2021-01-29 13:41:00 +08:00
    js Service Worker fetch event
    no1xsyzy
        14
    no1xsyzy  
       2021-01-29 13:43:03 +08:00
    https://stackoverflow.com/a/35558822/6202760 都不行
    但是你可以通过 onbeforeunload 来阻止跳转
    https://stackoverflow.com/a/2647601/6202760
    虽然
    no1xsyzy
        15
    no1xsyzy  
       2021-01-29 13:44:27 +08:00
    @no1xsyzy 虽然我不清楚这种不发生页面跳转的是否会生效……

    @sleepm fetch event 不能阻止自定义 scheme,除非你想替换页面上的每一个 js
    zictos
        16
    zictos  
    OP
       2021-01-29 13:45:44 +08:00
    @cjd6568358 #1
    defineProperty 可以修改 userAgent, 但是不能修改 location.href, 提示 Cannot redefine property: href


    下面是修改 userAgent 的代码, 修改后 userAgent 字符串就变成"new_ua"了:
    Object.defineProperty(navigator, 'userAgent', {
    value: 'new_ua',
    writable: false
    });
    console.log(navigator.userAgent);
    zjsxwc
        17
    zjsxwc  
       2021-01-29 13:45:49 +08:00
    js 做不到,只能在浏览器层面搞,比如安卓 webview 有 shouldOverrideUrlLoading 来处理

    https://stackoverflow.com/questions/16669046/android-webview-shouldoverrideurlloading-method
    azcvcza
        18
    azcvcza  
       2021-01-29 13:52:21 +08:00
    在浏览器里的 js 是有极限的,例如没办法在 onbeforeunload 里去阻塞关闭
    ciqulover
        19
    ciqulover  
       2021-01-29 13:54:17 +08:00 via iPhone
    对于 window.location 你想任何方式 re-define property 都是不可能的,这个对象你用页面同等级的 js 动不了他分毫。
    不过如果是浏览器插件就可以,如果目标脚本是异步加载,可以直接劫持掉请求,如果内联 script 就用 MutationObserver 。
    4 楼说的 jsproxy 可以参考一下。
    zictos
        20
    zictos  
    OP
       2021-01-29 13:54:24 +08:00
    @rekulas #12 如果很少有人去禁用的话, 那网站开发者在写 js 的时候就根本不会考虑 alert 被禁用的情况。虽然不能保证 100%的网站都有效,起码也可以保证 99%的网站有效
    sleepm
        21
    sleepm  
       2021-01-29 14:27:12 +08:00
    document.addEventListener('click', function(event) {
    target = event.target;
    if(target.nodeName == "A"){
    event.preventDefault();
    }else{
    console.log(target.nodeName);
    }
    });
    粗暴..
    JKKK
        22
    JKKK  
       2021-01-29 17:15:50 +08:00
    Proxy
    ysc3839
        23
    ysc3839  
       2021-01-29 17:33:30 +08:00
    这个问题应该从浏览器层面解决的。但不知道为什么 Chrome 有打开外部程序前提示的功能,却不给 Chrome Android 启用。
    顺便吐槽一下,Chrome Android 给人感觉问题很多,经常出现卡死的情况,不是说浏览器已经是多进程模型,标签页出现问题不会导致整个程序卡死了吗?
    shenyuzhi
        24
    shenyuzhi  
       2021-01-29 22:04:13 +08:00 via iPhone
    浏览器 api 不是普通的 js 对象。不建议做骚操作。
    anson2017
        25
    anson2017  
       2021-02-05 18:37:11 +08:00
    window.location.href = null
    zictos
        26
    zictos  
    OP
       2021-02-05 18:40:00 +08:00
    @anson2017 #25 不行,会跳转到当前页面所在路径下的 null 页面,是一个不存在的页面
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   941 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 22:12 · PVG 06:12 · LAX 14:12 · JFK 17:12
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.