Greasy Fork is available in English.

知乎 - 阻止知乎在 Firefox Android 下自动跳转至 zhihu://

刘看山啊,你知不知道,在没有安装你家客户端的情况下,用 Firefox Android 打开问答页面,会发生什么啊?

脚本作者
Crystal-RainSlide
今日安装
0
总安装量
415
得分
4 0 0
版本
1.0
创建日期
2020-09-14
最近更新
2022-03-28
许可证
blessing
应用到

新版本 Firefox(Fenix)不会跳转至协议无法识别的链接,不需要此脚本。


暂时不增加功能。

如果愿意使用样式管理器和广告屏蔽器实现功能:

屏蔽“继续浏览内容”弹窗:
  • 样式管理器
    @-moz-document domain(www.zhihu.com) {
    
    /* 底部悬浮 App 内打开 */
    .OpenInApp,
    /* 顶部 下载 App */
    .MobileAppHeader-downloadLink,
    /* 继续浏览内容弹窗 */
    .ModalWrap { display: none !important; }
    body.ModalWrap-body { overflow: auto !important; }
    
    }
  • 广告屏蔽器
    ! 底部悬浮 App 内打开
    www.zhihu.com##.OpenInApp
    ! 顶部 下载 App
    www.zhihu.com##.MobileAppHeader-downloadLink
    ! 继续浏览内容弹窗
    www.zhihu.com##.ModalWrap
    www.zhihu.com##body.ModalWrap-body:style(overflow: auto !important)

    注:AdBlock Plus 等广告屏蔽拓展可能不支持 :style()


这个脚本是怎么来的

如果使用 UA 符合 Android 移动设备的浏览器打开知乎的问答页面,在页面加载完成后,知乎会跳转到以 zhihu:// 开头的链接,变成网络错误页面。

不安装本脚本,直接使用 Firefox Android 访问的结果。

先看一下知乎是怎么实现的。

下面的代码来自 https://static.zhihu.com/heifetz/mobile.question-routes.ddbe47f5365563636c6f.js

window.addEventListener("load",function(){d.Android&&s&&(O.a.trackEvent(e,{id:5427,action:"Unknown"}),location.href="zhihu://".concat(u?"answer/".concat(u):"question/".concat(n),"?utm_source=mobile_web_scheme"))})}}

格式化后:

window.addEventListener(
    "load", function() {
        d.Android && s && (
            O.a.trackEvent(e, { id: 5427, action: "Unknown" }),
            location.href = "zhihu://".concat(
                u ? "answer/".concat(u) : "question/".concat(n),
                "?utm_source=mobile_web_scheme"
            )
        )
    }
)

处理后:

var trackEvent = function () {};
var deviceIs = { Android: true, iOS: false, WindowsPhone: "RIP" };
var shouldAutoOIA = true;
var isAnswer = false;
var answerId = null;
var questionId = "60475134";
window.addEventListener(
    "load", function() {
        deviceIs.Android && shouldAutoOIA && (
            trackEvent("", { id: 5427, action: "Unknown" }),
            location.href = "zhihu://".concat(
                isAnswer
                    ? "answer/".concat(answerId)
                    : "question/".concat(questionId),
                "?utm_source=mobile_web_scheme"
            )
        )
    }
)

看来,在 windowload 事件发射之后,知乎会直接执行 location.href = "zhihu://...",导航至对应链接。

然后,在没有安装知乎客户端的情况下,Chrome Android 会静默忽略知乎网页指向未知协议的导航行为,而 Firefox Android 会导航到网络错误页面,告诉用户知乎的这项创举。由于 load 事件发射后才会进行这个导航,这保证知乎能够收集到访问数据,而 Firefox Android 用户则无法轻易浏览知乎网页。

可是呢,

简单来说,目前,Firefox 下,用户脚本会受 CSP 的限制。 要么用 TemperMonkey 或者别的东西把知乎的 CSP 给整个干掉(可能会使 uBlock Origin 的一些规则失效),要么用户脚本就没法访问和设置除了 "a few properties of Window and Location objects" 以外的所有页面属性。

一些脚本编写者/使用者很早就已经了解到了这一点,我也不例外。 一般情况下,这就全完了。

但是,如果早就有专门用于这种情况的魔法呢?

有了这些,就可以通过 Xray vision 有限地访问和设置页面中的对象。

最后就有了这个知乎脚本。

但更关键的是,再也没有什么“一般情况”了,CSP 和 bug 挡不住魔法。 下次再遇到这个老问题,大不了把 Proxy 换成传统劫持,把 XMLHttpRequest 换成 window.wrappedJSObject.XMLHttpRequest… 不用早早放弃,更不用换浏览器。