ZWServe:面向开发者的零配置本地 CORS Web 服务器

一个二进制。无需运行时、无需任何依赖。拷到项目旁边,运行它,立刻通过 HTTP 或 HTTPS 提供任意目录——自带宽松 CORS、默认禁用缓存,并内置一张 30 年的 TLS 证书(用于 https://127.0.0.1)。完美用于本地开发、跨域测试,以及把 m3u8 流提供给网页播放器。

下载(预编译,免安装):

HTTPS 证书 + 一键安装脚本(可选,仅在使用 -https 时需要):

免费 · 自包含二进制 · 无需运行时 · 免登录


为什么你需要一个带 CORS 的本地服务器

大多数开发者迟早会用到本地 HTTP 服务器——预览构建产物、测试 m3u8 流、加载本地资源。问题是常用的那些一行命令都有短板:

  • python -m http.server 能用,但它不返回 CORS 头。一旦别的域(在线工具、已部署的应用、网页播放器)想 fetch 你的本地文件,浏览器就拦截。
  • Node 开发服务器vitewebpack-dev-server 等)适合完整项目,但只想服务一个文件目录时太重——需要 node_modules、配置、构建工具链。
  • 自己写 Express/Koa 每次都要写代码,而且还得记得把 CORS 配对。

ZWServe 就是补上这一块的:一个极小、单文件二进制,能提供任意目录,每个响应都带宽松 CORS 头,正确处理 OPTIONS 预检,且默认禁用缓存——再也不会被"旧缓存"幻觉坑。拷进去,运行,完事。

ZWServe 做了什么

给它一个目录(默认当前目录)和一个端口,它会:

  1. 提供 目录的 HTTP 服务:目录列出、index.html 自动索引、Range 支持(大媒体可拖动进度条)。
  2. 注入 CORS 头Access-Control-Allow-Origin: * 等),并对 OPTIONS 预检返回 204 No Content
  3. 默认禁用缓存Cache-Control: no-store),刷新永远拿到磁盘上最新的文件。

就这三件事,做对,零配置。

核心特性

特性 说明
零配置 不带参数运行,就以当前目录、8000 端口提供服务。整个使用就这么简单。
宽松 CORS 每个响应都带 Access-Control-Allow-Origin: * 及跨域 fetch/XHR 所需的头。
正确预检 OPTIONS 请求返回 204 No Content 并带正确 CORS 头——没有 “method not allowed” 的意外。
默认禁用缓存 每个响应都带 Cache-Control: no-store,刷新永远拿最新文件。加 -cache 可允许浏览器缓存(演示/生产用)。
可选 HTTPS -https 即用内置 30 年自签证书(绑定 127.0.0.1 + localhost)通过 TLS 提供服务;也可用 -cert/-key 换自己的证书。
Range 支持 支持 Range/Accept-Ranges,播放器可拖动定位、断点续传大文件。
目录列出 + 索引 浏览目录会列出内容;有 index.html 时自动作为入口。
无运行时、无依赖 每个平台一个自包含二进制,不用装 Python、Node 或任何虚拟机。
可选端口与目录 -port(默认 8000)、-dir(默认 .)。

三端快速上手

下载对应系统的二进制,放到要服务的目录里,运行即可。

Windows

# 以当前目录为根,默认 8000 端口(CORS + 禁缓存已开启)
.\zwserv-win.exe

# 自定义端口和目录
.\zwserv-win.exe -port 9000 -dir .\dist

macOS(Apple Silicon)

chmod +x zwserv-macos
./zwserv-macos                  # 当前目录,8000 端口
./zwserv-macos -port 9000 -dir ./dist

首次运行 macOS 可能拦截未签名二进制。右键 → 打开 → 确认;或先执行 xattr -d com.apple.quarantine zwserv-macos

Linux

chmod +x zwserv-linux
./zwserv-linux                  # 当前目录,8000 端口
./zwserv-linux -port 9000 -dir ./dist

启动时 ZWServe 会打印所有可访问地址(全部本地 IPv4 + localhost),直接复制即可:

ZWServe — from zwplayer.com (local CORS web server)
-------------------------------------------------
ZWServe — minimal CORS local web server
---------------------------------------------------------
serving : /home/me/project/dist
port    : 8000
cache   : off (no-store — every refresh fetches the latest)

Serving at:
  http://192.168.1.20:8000/
  http://localhost:8000/

为什么选择 ZWServe

ZWServe 在前端本地开发和跨域测试场景尤为出色——凡是原本要用 python -m http.server、笨重的 Node 开发服务器、或仅仅为了绕过 CORS 而搭一个反向代理的地方,它都能替代。它是开发时提供本地文件的快速、零配置平替。

1. 拷过去就能直接用——无需配环境

什么都不用装。ZWServe 是单一自包含二进制——没有 Python、没有 Node、没有 node_modules、没有虚拟环境、没有包管理器。拷到项目旁边(或在 ~/bin 里留一份)就能运行。新机器、同事的笔记本、CI 机器上都能直接用。这让快速预览、分享构建产物走评审、几秒钟起一个临时服务器都变得很顺手。

2. 内置 CORS——跨域测试不再头疼

这是 ZWServe 对开发最大的价值。现代工作流里到处都是跨域请求,而浏览器的 CORS 规则经常挡路:

  • 在在线播放器里测本地 m3u8。 ZWPlayer 跑在 zwplayer.com。当它 fetch 你的 localhost:8000/master.m3u8 时,这是跨域请求,普通服务器(以及文件系统)都会拦截。ZWServe 的 Access-Control-Allow-Origin: * 直接放行,正确的 OPTIONS 处理也保证了播放器在真正请求前发出的预检能成功。
  • 开发期前端对接远端 API。 把本地 fixture 用 ZWServe 提供出来,浏览器里的工具/fetch 不会被 CORS 拦。
  • Mock 第三方 API 和资源。 提供静态 JSON / 图片 / 字幕,从任意页面跨域加载,无需代理。

因为 CORS 始终开启且始终正确,你不再跟浏览器较劲,能把精力放回功能本身。

3. 默认禁用缓存——再也不会"我改的怎么没生效?"

本地服务器最耗时的调试陷阱就是陈旧缓存:你改了文件、刷新、什么都没变——因为浏览器用了旧版本。ZWServe 默认对每个响应都发 Cache-Control: no-store, no-cache, must-revalidate(以及配套的 Pragma/Expires),所以每次刷新都回源拿最新文件。不用强制刷新、不用开 DevTools 的"禁用缓存"、不用加版本号查询参数。

万一你确实要缓存(给客户演示、做生产级静态托管),打开即可:

./zwserv-macos -cache    # 允许浏览器缓存

在后台运行 ZWServe

开发时要长期挂着服务器,就把 ZWServe 脱离终端运行,关掉窗口也不影响。

Linux 和 macOS —— nohup

nohup(no hangup)让进程脱离终端,注销后仍继续运行。把输出重定向到日志文件,方便事后查看:

# 后台启动,日志写到 zwserv.log
nohup ./zwserv-linux -port 8000 -dir ./dist > zwserv.log 2>&1 &

# 记下打印的 PID(如 [1] 12345),然后确认
jobs -l
# 或
pgrep -fa ZWServe

# 实时跟日志
tail -f zwserv.log

# 之后停止
kill $(pgrep -f zwserv)
  • > zwserv.log 2>&1 把标准输出和标准错误合并写入日志文件。
  • 末尾的 & 把它放到后台。
  • nohup 让它忽略 SIGHUP,所以关掉终端它仍在跑。

Windows —— Start-Process(PowerShell)

PowerShell 的 Start-Process 把 ZWServe 起在独立进程里,脱离你的控制台:

# 脱离启动,日志写到 zwserv.log
Start-Process -FilePath ".\zwserv-win.exe" -ArgumentList "-port","8000","-dir",".\dist" `
              -WindowStyle Hidden -RedirectStandardOutput "zwserv.log" -RedirectStandardError "zwserv.err"

# 之后查找
Get-Process zwserv-win

# 停止
Stop-Process -Name zwserv-win

Windows —— start(命令提示符)

cmd 里,内置 start 命令会弹到新窗口脱离:

start "zwserv" /min zwserv-win.exe -port 8000 -dir .\dist

要在 Windows 上彻底无窗口脱离运行,优先用上面 PowerShell 的 Start-Process

用 HTTPS 提供服务(内置 TLS 证书)

有些功能必须用 HTTPS 才能测——Secure-Context 专属 API(Service Worker、getUserMedia、剪贴板、crypto.subtle),或任何在安全源上行为不同的代码。ZWServe 内置了一张 30 年自签证书,绑定 127.0.0.1localhost,加一个开关就能开启 HTTPS,对着 https://127.0.0.1:8000 测试。

1. 用 HTTPS 提供服务

# 用内置证书(绑定 127.0.0.1 + localhost)
./zwserv-win.exe -https
./zwserv-macos -https
./zwserv-linux -https -port 8443

# 或用自己的证书/私钥
./zwserv-win.exe -https -cert /path/my.crt -key /path/my.key

不信任证书时,浏览器会照例弹"自签名证书"警告。要让 https://127.0.0.1 显示绿色锁、无警告,把证书装进系统信任库(下一步)。

2. 信任内置证书(一键)

下载本页顶部的证书和对应系统的安装脚本,然后:

  • Windows —— 右键 install-cert-windows.bat以管理员身份运行。它执行 certutil -addstore Root 把证书加入受信任的根证书颁发机构。
  • macOS —— chmod +x install-cert-macos.sh && sudo ./install-cert-macos.sh。通过 security add-trusted-cert 把证书加入系统钥匙串并标记为受信任根。
  • Linux —— chmod +x install-cert-linux.sh && sudo ./install-cert-linux.sh。装入发行版 CA 目录并执行 update-ca-certificates/update-ca-trust

装完重启浏览器,打开 https://127.0.0.1:8000/——无警告。

3. 自己导出证书(可选)

也可以随时把内置证书写到当前目录,再手动安装:

./zwserv-win.exe -writecert     # 在服务目录写出 zwserver.crt / .key / .pem

关于这张证书(请读)

  • 该证书(及其私钥)直接编进了每个 ZWServe 二进制——所以所有用户共用同一把私钥。这只适合 127.0.0.1/localhost 本地测试(无网络暴露)。切勿把这个证书的 HTTPS 端点暴露到公网——拿到二进制的人就拿到了私钥。(要让浏览器信任它,仍需通过下面的脚本安装;该证书不在任何公共根证书库里。)
  • 若要每台机器独立的本地 CA,用 mkcert 这类工具生成证书,再用 -cert/-key 传入。
  • 证书有效期 30 年(2026–2056),SAN = localhost + ::1 + 127.0.0.1,RSA 2048。

ZWServe 与 ZWPlayer(以及 M3U8Grab)搭配

ZWServe 是为 ZWPlayer 工作流而生,但它本身是通用服务器,干什么都行。

把 m3u8 流提供给 ZWPlayer:

  1. M3U8Grab 下载流(把整棵 HLS 树镜像成自洽目录)。
  2. 用 ZWServe 提供这个目录:./zwserv-linux -dir ./media/myvideo
  3. 打开 ZWPlayer,粘贴 http://localhost:8000/master.m3u8,即可播放——所有字幕轨自动挂载。

因为 ZWServe 提供了 ZWPlayer 访问你 localhost 所需的 CORS 头,整个链路"开箱即用"——无需代理、无需特殊构建、无 CORS 报错。

不止视频: 用 ZWServe 预览任意静态站点构建(-dir ./dist)、提供本地 API fixture,或通过打印的局域网地址在多设备间共享文件。

命令行参数参考

参数 默认值 说明
-port 8000 监听的 TCP 端口
-dir . 要服务的目录(默认:当前目录)
-cache false 是否允许客户端缓存。默认关闭(no-store),最适合开发。
-https false 用内置自签证书(绑定 127.0.0.1/localhost)通过 HTTPS 提供服务。
-cert "" 自定义 TLS 证书路径(PEM)。指定即启用 HTTPS,需配合 -key
-key "" 自定义 TLS 私钥路径(PEM)。指定即启用 HTTPS,需配合 -cert
-writecert false 把内置证书导出到服务目录的 zwserver.crt/.key/.pem 后退出。
-h 显示使用说明。

常用示例

# 默认:当前目录,8000 端口,禁缓存
./zwserv-win.exe

# 自定义端口预览构建产物
./zwserv-win.exe -port 3000 -dir ./dist

# 允许缓存(演示 / 生产级)
./zwserv-win.exe -cache

# 在 Linux/macOS 后台运行并记日志
nohup ./zwserv-linux -port 8000 -dir ./dist > zwserv.log 2>&1 &

常见问题

支持 HTTPS 吗?

支持。加 -https 即用内置 30 年自签证书(绑定 127.0.0.1/localhost)通过 TLS 提供服务,也可用 -cert/-key 用自己的证书。详见上文的用 HTTPS 提供服务。要让内置证书无警告,运行对应系统的一键安装脚本。

长期运行安全吗?

ZWServe 监听 0.0.0.0,所以局域网可达——方便在别的设备上测,但在共享网络里要留意。它只是静态文件服务器,没有写/删操作,不会修改或删除你的文件。

浏览器一直缓存某个文件,怎么办?

通常不用管——默认就禁用缓存了。如果你显式开了 -cache 又想让某个文件始终最新,把 -cache 去掉即可。

被杀毒软件 / macOS 拦截了。

因为这些二进制没有签名,部分系统会拦截。macOS:右键 → 打开 → 确认,或执行 xattr -d com.apple.quarantine <文件>;Windows:在 SmartScreen 里点"更多信息" → “仍要运行”。

总结

ZWServe 是你随身揣着的本地服务器:单一自包含二进制,无需运行时、无需配置。它提供任意目录,CORS 始终开启缓存默认关闭、预检处理正确——让你能测试跨域请求、把 m3u8 提供给在线播放器、或预览构建产物,都不用跟浏览器较劲。临时检查前台跑,长期开发就用 nohup / Start-Process 挂后台。