Greasy Fork is available in English.
自动在每条推文下方显示“Twitter for ...”来源,支持登录用户请求头,还原 iOS 插件逻辑;并在页面内改写 HomeTimeline / TweetDetail 响应体,去除广告
一个用于 X / Twitter 的油猴脚本:
- 在帖子详情页显示推文来源(如
Twitter for iPhone)- 在页面内部改写
HomeTimeline/TweetDetailGraphQL 响应体- 去除页面广告
这个脚本主要做两件事:
显示推文来源
在帖子详情页中,为主推文补充来源标签,例如:
📱 来源:Twitter for iPhone📱 来源:Twitter Web App📱 来源:Twitter for Android通过修改GraphQL响应体去除页面广告
脚本会在页面内部拦截并处理:
HomeTimelineTweetDetaildocument-start,也就是页面脚本很早阶段就开始生效。x.com 或 twitter.com 测试。如果你已经有脚本文件,可以直接在扩展中导入或粘贴文件内容。
这份脚本需要以下权限:
GM_xmlhttpRequest
用于跨域请求 api.twitter.com,获取推文来源
@connect api.twitter.com
明确允许连接来源接口域名
@run-at document-start
让脚本尽可能早于页面业务脚本运行,这对 GraphQL 响应体改写很关键
打开任意帖子详情页,例如:
https://x.com/<用户名>/status/<tweetID>
脚本会自动:
tweetIDsource 字段如果一切正常,你会在详情页看到类似:
📱 来源:Twitter for iPhone
脚本不需要手动按钮。
只要页面请求命中了以下 GraphQL 接口之一:
/i/api/graphql/.../HomeTimeline/i/api/graphql/.../TweetDetail脚本就会自动尝试改写响应体。它通过包装页面上下文中的:
fetchXMLHttpRequestPromise.prototype.then来尽量保证前端消费到的对象也是处理后的
脚本会请求这个接口:
https://api.twitter.com/2/timeline/conversation/<tweetID>.json?include_ext_alt_text=true&include_reply_count=true&tweet_mode=extended
然后从响应里读取:
globalObjects.tweets[tweetID].source
这个字段通常是一段 HTML,例如:
<a href="http://twitter.com/download/iphone" rel="nofollow">Twitter for iPhone</a>
脚本会去掉 HTML 标签,只保留纯文本
Userscript 本身不能像 MITM 代理那样在系统网络层直接改包,所以这份脚本采取的是:
HomeTimeline / TweetDetail 数据结构做过滤。这意味着它更接近“前端运行时修正”,而不是代理级响应体替换。
脚本使用 Map 做简单缓存,避免同一个 tweetID 被重复请求
当来源接口出现:
404脚本会自动重试一次,尽量减少偶发失败导致的来源不显示
X / Twitter 是单页应用,普通脚本只在首次加载执行往往不够 这份脚本会通过轮询 pathname 的方式监听路由变化,在切换到新的帖子详情页后重新初始化来源标签逻辑
脚本使用 MutationObserver 观察详情页变化。
如果来源标签因为页面重渲染被移除,会尝试重新挂回去
这份脚本更适合这些用户:
可能原因包括:
脚本内部已经通过:
findTweetArticle(tweetID)MutationObserver来尽量缓解这些问题,但仍可能受 X 前端结构变化影响。
因为这不是系统代理层改包,而是浏览器页面内改写。
如果 X 的前端实现、字段路径、Promise 链、缓存逻辑发生变化,可能会影响改写效果。脚本已经同时处理了:
fetchXMLHttpRequestPromise.prototype.then因为如果脚本在页面主逻辑之后才注入,首批 GraphQL 请求可能已经完成,这会导致改写层错过最关键的响应。
因此脚本使用了:
// @run-at document-start
来尽量提前生效。
x.com / twitter.comMIT 狼小雨