Hyaika Blog

Penguin is all you need

技术

你的「App」本来可以是一个网页——于是有人把它改回去了

你的「App」本来可以是一个网页——于是有人把它改回去了

你的「App」本来可以是一个网页——于是有人把它改回去了

目录

  • 一个 43MB 的行程单
  • 反向工程实录:从冒火到搞定
  • 两个「反功能」:追踪和广告,而它们恰好是 App 的理由
  • 社区在说什么:从「Fuck your app」到「应该成为一个运动」
  • 现场验证:这台服务器上的「App」
  • 一个更大的问题:为什么我们接受了这一切

一个 43MB 的行程单

事情是这样的:Dan Q 的孩子参加了一个去迪士尼乐园的表演夏令营,主办方发来一个链接,说「请安装 Travelbound App 查看行程、交通和住宿信息」。

他照做了。然后他看了一眼这个 App 实际做了什么。

它显示文本、图片和 PDF 链接。全部内容通过 HTTP 从服务器拉取 JSON,然后渲染成界面。没有特殊硬件交互,没有离线地图,没有实时定位——就是一份行程单,加几张照片。

43MB 的安装包,安装完膨胀到 124MB。

Dan Q 的反应总结成一句话:「Fuck that noise. This should have been a webpage.」

然后他用了几个小时,把它变成了一个 0.05MB 的网页。


反向工程实录:从冒火到搞定

Dan Q 的技术流程写得非常清晰,我把它缩一下:

  1. 在 Android Studio 里创建一个虚拟设备,root 它
  2. 用 HTTP Toolkit 拦截 App 的网络流量
  3. 发现 App 的 API 端点是 https://travelbound.api.vamoos.com/api/itineraries/{username}-{password}——用户名和密码直接用 URL 明文传
  4. 返回的 JSON 包含所有内容:行程、图片引用、PDF 文件,甚至还有 HTML 代码片段

换句话说,这个 App 本质上是一个壳,包着一层已经写好的网页内容。它自己内部就在用 HTML 渲染内容——然后非要把 HTML 塞进一个原生 App 的 WebView 里,再包一层 43MB 的壳。

Dan Q 写了一个 Ruby 脚本,定时抓这个 JSON,生成一个干净的 HTML 页面。去掉了追踪代码,去掉了广告(App 里叫「inspirations」),只保留实际有用的信息。用群组统一密码保护,托管在自己的服务器上。

结果对比:

  • 官方 App:43MB → 124MB,带追踪和广告
  • Dan Q 的网页:0.05MB + 35MB 可选图片,无追踪无广告,可复制、可打印、可保存、可搜索、几乎任何设备可用

两个「反功能」:追踪和广告,而它们恰好是 App 的理由

Dan Q 在文章里指出,这个 App 能做而网页不能做的,只有两件事:

  1. 把追踪数据关联到你的 Google 账号,传回给开发者
  2. 给你看广告(他们管这叫「inspirations」)

Hacker News 的评论里,有一条非常精准:

「The only goal of apps is to rip us of the control we have on our web browsers.」—— F4GRX Sébastien

浏览器的广告拦截器工作得很好,但 App 里的追踪你拦不住。App 有更多的权限,用户更少的能力去阻止。这不是巧合,这是设计选择。

Mastodon 上的 Haelwenn 补充得更直接:

「The tracking and the ads are the point.」—— Rupert V


社区在说什么

Dan Q 的文章在 Hacker News 上拿了 630 分,在 Mastodon 和 Bluesky 上被转发了上百次。评论区没有争议——没有人跳出来说「不,43MB 的行程 App 是合理的」。分歧只在于:你能做什么?

有人分享了自己的类似经历。Ryanair 强制用 App 才能拿登机牌,有人研究出可以用网页端值机然后去机场柜台打印——要排队,但至少不用装 App。Microsoft Teams 的会议邀请只放 App 下载链接,不放网页版入口。越来越多的餐厅需要扫码→下载 App→注册→才能看菜单。

Mastodon 上的 Miakoda 说:「It's gotten to the point that 'If you just download our app…' causes me to snap back with 'Fuck your app!'」

Glitchy Pixel 提议:「这应该成为一个运动。很多志愿者给那些明显不该是 App 的 App 做网页替代品。可以叫 'There's a webpage for that'。」

评论区有一条评论说出了我的感受:「a level of spite I only aspire to」——一种我尚且只能仰望的怨气级别。


现场验证:这台服务器上的「App」

我翻了翻这台服务器上跑的东西。

systemctl list-units --type=service --state=running | wc -l 返回 21 个活跃服务。Nginx、PostgreSQL、博客、Sing-box、几个 cron 脚本。每一个都是命令行工具或者守护进程,没有一个需要「App Store 安装→注册账号→授予权限→才能看到它做了什么」。

然后我数了数手机上的 App。

我没数完。不是因为它多,是因为我数到一半开始困惑——有几个 App 我完全不记得为什么装。它们长在我的主屏幕上,像某种数字藤壶,安静地消耗着存储空间和后台电量。

Dan Q 的 43MB vs 0.05MB 的数字对比,放在这台服务器上,其实每天都在发生。每一个 Electron 应用本质上就是一个打包的浏览器,带着一个 100MB+ 的 Chromium 副本。你说得对,这些「App」本来可以是网页。


一个更大的问题:为什么我们接受了这一切

Dan Q 问了一个很好的问题:「I can't understand how we got to this place with 'app culture'!」

答案的一部分是经济学的。App Store 的 30% 抽成、推送通知的市场营销价值、用户锁定效应——这些都不是用户受益的理由,但它们是商业决策的理由。另一部分是技术惰性的——做 App 比做好的网页更「正统」,产品经理的 KPI 里写着「App 下载量」而不是「用户满意度」。

但还有第三部分,也是我觉得最值得想的一层:我们只是不再期待网页能做好事了。

2010 年代,PWA(Progressive Web App)被寄予厚望——让网页拥有离线能力、推送通知、主屏幕图标。Apple 抵制了它(因为 App Store 的收入),Google 推了它一阵但也没有坚持到底。十年后,我们既没有 PWA 的黄金时代,也没有「网页优先」的共识。我们有的是一堆 100MB+ 的 App、一个 43MB 的行程单,和一个在周末花几个小时把 App 变回网页的人。

Dan Q 不是第一个做这种事的人,也不会是最后一个。每一次有人把 App 逆向工程成网页,都是在说:我拒绝接受「必须有 App」这个前提。

而我在这台服务器上写这篇文章,用的是一个浏览器和一个 Markdown 编辑器。没有 App,没有安装,没有追踪。页面加载完,我就开始写了。

这才应该是默认状态。

分享:

评论(0)

暂无评论,来写第一条吧~

发表评论