这一章没有新知识。前面十六章学的东西够用了,这一章只做三件事:给你一条四周练习路线、出 5 道练习题让你自测、最后做个结课小结。
学编程和学开车一样:看懂 ≠ 会写。只有自己动手敲过、错过、改对过,才算真的学会。
这一页怎么用
① 四周计划:每周做完就点左边的圆圈打勾,看着进度条涨满。
② 练习题:先自己想,能跑的题先点「运行」看结果,想好了再点「看答案」,对一下标准答案和解析,尤其看「常见错」是不是你刚犯的那个。
③ 代码块右上角有「复制」,可以把代码粘到浏览器控制台或编辑器里自己改着玩。
不用贪快,一周攻一块。每周都给了「过关标准」,达不到就多练两天再往下走——地基不牢,后面全是糊涂账。打勾只在本次打开页面时有效,关掉就清零,真正的进度记在你练没练上。
每天打开浏览器控制台,写 20 分钟。内容就四样:变量(let / const 存东西)、字符串方法(includes 查包含、split 拆开这类)、数组四件套(filter 筛、map 变、find 找、forEach 挨个过)、函数(把一段活儿打包,喊一声就干)。
x => … 这种写法)。还是在控制台练两件事:一是 JSON 互转——JSON.parse(文字变对象)、JSON.stringify(对象变文字),来回转到熟;二是 fetch 拿数据——找一个公开接口(比如天气接口),把返回的 JSON 取回来,打印出其中某一个字段(比如温度)。
去 Cloudflare 后台建一个练习用的 Worker,照第十章的「路由」写法练:不同网址走不同代码。再照实战一完整做一遍 KV 短链接(把长网址存进 KV,访问短码就跳过去)。做完拿手机浏览器打开短链接,亲眼确认能跳转。
先读:挑一个你现在正在用的现成模块,把它的每一行声明逐行看懂(什么时机跑、对哪类请求、要不要响应体)。再改:照实战二,自己动手改掉一个接口返回里的某个字段。最后去 App 的日志里确认:脚本真的跑了,而且 $done 正常结束、没有报错。
规矩都一样:先自己想 → 点「运行」看结果(能跑的题)→ 再点「看答案」。直接看答案 = 白做,这章就是查漏补缺的。
有节点名数组 ["香港01","美国02","香港03"]。请写一行代码:只留下名字里带「香港」的,再用逗号拼成一个字符串。
["香港01","美国02","香港03"].filter(x => x.includes("香港")).join(",")
// filter:挨个问 includes("香港"),答「是」的留下
// join(","):把留下的用逗号连成一个字符串
运行结果:"香港01,香港03"
解析:分两步。第一步 filter(筛选):它挨个拿数组里的名字去问箭头函数,includes("香港") 返回「真」的就留下、返回「假」的就扔掉,所以留下香港01 和香港03。第二步 join(",")(连接):把剩下的数组用逗号粘成一个字符串。
写一个函数:给它一段文字(是某个接口返回的 JSON 字符串),返回里面 data.list 这个列表的长度;如果这段文字根本不是合格的 JSON(解析失败),返回 -1,不许让程序崩掉。
function getListLength(text) {
try {
const obj = JSON.parse(text); // 文字转对象,这一步可能抛错
return obj.data.list.length; // 一层层点进去,取列表长度
} catch (e) {
return -1; // 出错就走这里,返回 -1
}
}
解析:关键在 JSON.parse(解析)这个动作靠不住:文字是好 JSON 它就转成对象,文字是坏的它直接抛错,没人接的话整个脚本当场停摆。所以把 parse 和取值都放进 try(试着做)里,一旦抛错,自动跳到 catch(接住)里返回 -1。这就是处理「外部给的数据」时的保命写法:数据不是你产的,永远假设它可能是坏的。
return JSON.parse(text).data.list.length。数据好的时候没事,哪天接口抽风返回一句报错文字,脚本立刻崩掉——而且往往是在你没看着的时候崩。回到第 3 周做的实战一(KV 短链接)。现在给这个 Worker 加一个新接口:访问 /api/stat?key=gh 时,返回短码 gh 这条短链被访问过多少次,用 JSON 形式返回。假设每次跳转时已经把次数存进了 KV,键名是 count: 加短码。
if (url.pathname === "/api/stat") {
const key = url.searchParams.get("key"); // 取问号后面的 key=gh
const n = Number(await env.LINKS.get("count:" + key)) || 0;
return Response.json({ key, count: n }); // 以 JSON 形式返回
}
解析:三点。① 路由判断靠 pathname(路径部分):url.pathname 只含 /api/stat,不含问号后面的参数,所以拿它跟字符串比正合适;参数则用 url.searchParams.get("key") 单独取。② KV 读出来的是字符串:哪怕存的是次数,读出来也是文字,必须用 Number() 转成数字才能用。③ 兜底 0:这条短链一次都没被点过时,KV 里根本没有这个键,读出来是空的,转完是 NaN(不是数字),靠 || 0 兜成 0,返回给人看才正常。
写一个 http-request 类型的脚本(请求发出去之前跑的那种):给某个域名的所有请求,统一加上一个请求头 X-From: module。用法忘了可以回翻第十二章讲的 $done({headers})。
$done({
headers: {
...$request.headers, // 先把原有请求头全部摊开带上
"X-From": "module" // 再加上我们要的新头
}
});
解析:http-request 脚本里想改请求头,就用 $done({ headers }) 把改好的头部交回去,App 会拿这份头部去发请求。关键在 ...$request.headers 这一行:三个点叫展开,意思是「把原来所有的头一个不少地先放进来」,然后再补上 X-From。这样新头有了,原来的头(比如登录凭证、设备信息)也都还在。
$done({ headers: { "X-From": "module" } })。这一交,请求就只剩这一个头了,原来的头全丢——轻则接口报错,重则登录状态没了、App 直接用不了。改头先展开原头,这一步永远不能省。找一个你现在正在用的模块,逐行注释它的 [Script] 声明,再注释它脚本的第一段代码。最后用大白话说清三件事:它在什么时机跑、对哪一类请求下手、做了什么。
第一步:逐行拆 [Script] 声明
去广告 = type=http-response, pattern=^https://api\.example\.com/feed, requires-body=true, script-path=ad.js
// type=http-response → 响应回来之后才跑这个脚本
// pattern=网址规则 → 只对 feed 接口的网址触发,别的请求不碰
// requires-body=true → 需要拿到响应体(返回的数据正文)
// script-path=ad.js → 真正干活的脚本文件是 ad.js
| type=http-response | 时机:服务器把数据返回来之后、App 显示之前,脚本插进来改数据。 |
| pattern=…/feed | 对象:只有网址对上这个规则的请求才触发,也就是信息流(feed)接口,其他接口不受影响。 |
| requires-body=true | 条件:要改返回内容,就必须声明需要响应体;不写这一项,脚本根本拿不到数据正文。 |
第二步:注释脚本第一段
const obj = JSON.parse($response.body);
// $response.body 是响应正文,此时还是一段文字
// JSON.parse 把文字转成对象,后面才能 . 点着取字段、删广告
第三步:一句话总结。这个模块在信息流接口的数据返回来之后、App 显示之前跑,先把返回的文字转成对象,再把里面的广告条目删掉、交回给 App。所以你刷信息流时看不到广告——不是广告没下发,是下发了又被脚本在半路删掉了。
十七章到这里就全部结束了。回头看看,你其实已经走完了一整条线:
变量、字符串、数组、函数、对象、JSON、异步——能自己在控制台写小段代码解决问题。
能在 Cloudflare 上写按网址分发的服务,用 KV 存数据,做得出短链接这种完整的小工具。
Surge / Loon / REX 的模块声明能逐行读懂,能改请求头、改响应字段,知道去日志里验货。