游客发表
浏览器地址栏里敲下那个以 .js 结尾的脚本链接,回车,文件页面没跳转,下载屏幕上直接铺开一大段代码。脚本这就是文件脚本文件下载最原始的样子——服务器把 Content-Type 设成 application/javascript 或者 text/plain,浏览器就不解析,下载直接展示文本。脚本想存到本地?文件右键另存为,或者 Ctrl+S。下载简单粗暴,脚本但够用。文件
问题出在自动化场景里。下载比如你写了个爬虫,脚本或者用 Puppeteer 跑无头浏览器,文件想批量抓取某个页面上引用的下载脚本文件,靠手动右键显然不现实。这时候就得看 HTTP 响应头里的 Content-Disposition。如果服务器设了 attachment; filename="app.js",浏览器会弹下载框;没设的话,浏览器默认内联展示。很多 CDN 为了省事根本不设这个头,所以你得自己写逻辑判断。
我遇到过一种情况:某网站把核心业务逻辑拆成十几个 chunk,文件名带 hash,比如 main.7f3a2b.js。这些文件通过动态 import 加载,network 面板里能看到请求,但直接访问 URL 会返回 403——服务器校验了 Referer 和 Cookie。这时候光靠 wget 或 curl 裸抓是不行的,得把请求头完整复制过去。Chrome DevTools 里右键某个请求,选 Copy as cURL,粘到终端里跑,基本能拿到文件。这是个体力活,但比写脚本模拟登录省事。
另一种常见坑是 MIME 类型错误。服务器返回 Content-Type: text/html,但内容其实是 JS。浏览器会尝试当 HTML 解析,结果一片乱码。你下载下来发现文件打不开,编辑器里全是转义字符。解决办法也简单:下载时强制指定二进制模式,别让任何中间层做编码转换。Python 的 requests.get(url, stream=True) 配合 iter_content 写文件,比直接 .text 靠谱得多。
还有更隐蔽的:脚本文件被 gzip 压缩后传输,但响应头里 Content-Encoding: gzip 没写对,或者你用的下载工具不自动解压。拿到的文件用 file 命令一看,显示 "gzip compressed data",改后缀为 .gz 再解压才能得到真正的 .js。这事我在抓某电商平台的前端监控脚本时踩过,折腾了半小时才反应过来。
说个实际案例。上个月帮朋友抓一个在线工具站的加密算法,核心逻辑在一个叫 crypto.min.js 的文件里。直接访问 URL 返回 200,但内容是一段混淆过的代码,变量名全是 _0xabc123 这种。下载没问题,问题在于怎么读。我用 curl -O 存下来,扔进 VS Code,装了 prettier 格式化,再配合 de4js 这类在线工具反混淆,才勉强看出点逻辑。下载只是第一步,后面的事更耗时间。
如果你用 Node.js 写下载脚本,axios 的 responseType: 'arraybuffer' 是关键。别用 'text',否则遇到非 UTF-8 编码的脚本会丢字节。写文件时用 fs.writeFileSync(path, Buffer.from(response.data)),保证二进制一致性。我见过有人用 fs.writeFileSync(path, response.data, 'utf-8'),结果下载下来的文件比原始大小少了几个字节,跑起来报语法错误,查了半天才发现是编码问题。
另外,有些网站会检测 User-Agent。你用 Node 默认的 UA 去请求,返回 403 或者一个空文件。改成和浏览器一致的 UA 字符串,立马正常。这不是什么高深技术,但不知道就卡住。我习惯在下载脚本里硬编码一个 Chrome 的 UA,省得每次调试。
最后提一句并发。批量下载几十个脚本文件时,别一股脑 Promise.all 全发出去。目标服务器可能限流,返回 429。用 p-limit 控制并发数在 3 到 5 之间,稳当。下载完记得校验文件大小和 MD5,防止中途截断。这些细节没人会写在文档里,都是踩坑踩出来的。
友情链接