如何用 serve.py 本地起服务预览 Godot Web 导出并理解 COOP/COEP 响应头?
【免费下载链接】godotGodot Engine – Multi-platform 2D and 3D game engine项目地址: https://gitcode.com/GitHub_Trending/go/godot
如果你已经用 Godot 导出了 Web 版项目,直接双击导出的.html文件在浏览器里打开往往跑不起来:Godot 的 Web 导出依赖 fetch 加载 wasm 等资源,且启用线程的构建要求站点是 "cross-origin isolated"(需要 COOP/COEP 响应头)。仓库里的 platform/web/serve.py 就是解决这件事的轻量工具:它在本机起一个静态文件服务器,并在每个响应上自动附带Cross-Origin-Opener-Policy: same-origin、Cross-Origin-Embedder-Policy: require-corp和Access-Control-Allow-Origin: *三个响应头,这样你在本地预览导出产物时,线程、音频等功能所依赖的 cross-origin isolated 环境就齐了。
前置条件
- 已安装 Python 3(脚本第一行是
#!/usr/bin/env python3,只用到标准库,不需要额外装包)。 - 已完成 Web 导出。
serve.py默认的根目录是platform/web/相对路径下的../../bin,也就是仓库根目录的bin/——所以把导出的项目文件(.html入口页、.wasm、.pck等)放到仓库根目录的bin/下,或按下一步用--root指定你的导出目录。
启动本地服务
serve.py接受三个参数(见 serve.py 的 argparse 定义):
| 参数 | 说明 | 默认值 |
|---|---|---|
-p, --port | 监听端口 | 8060 |
-r, --root | 作为站点根目录提供服务的目录,路径相对platform/web/解析 | ../../bin(即仓库根的bin/) |
-n, --no-browser | 不自动打开默认浏览器 | 默认会自动打开浏览器 |
最短主路径(导出文件已放在bin/下):
python3 platform/web/serve.py导出在别处时指定目录,例如导出目录是/tmp/my-game-export:
python3 platform/web/serve.py -r /tmp/my-game-export -p 8060不想自动弹浏览器的开发调试场景:
python3 platform/web/serve.py -n脚本自身会先chdir到它所在的platform/web/目录,所以从仓库任意位置运行都可以,-r的相对路径一律相对platform/web/计算。
启动后输出分两种:
Opening the served URL in the default browser (use `--no-browser` or `-n` to disable this): http://127.0.0.1:8060或(加了-n时):
Serving at: http://127.0.0.1:8060服务使用 dual-stack socket(同时接受 IPv4/IPv6,见DualStackServer),地址绑定为("", port),即监听本机所有网络接口的指定端口;浏览器里访问上面打印出的http://127.0.0.1:<port>地址,再进到导出目录里的入口 HTML 文件即可。按 Ctrl+C 会打印Keyboard interrupt received, stopping server.并关闭服务,这是脚本内置的正常退出方式。
这三个响应头分别做了什么
serve.py里的CORSRequestHandler在每个 HTTP 响应上追加三个头:
self.send_header("Cross-Origin-Opener-Policy", "same-origin") self.send_header("Cross-Origin-Embedder-Policy", "require-corp") self.send_header("Access-Control-Allow-Origin", "*")Cross-Origin-Opener-Policy: same-origin(COOP):把页面划进独立的"窗口组",只有同源的文档共享该组。Cross-Origin-Embedder-Policy: require-corp(COEP):要求页面加载的子资源都携带显式的跨源权限声明。
两者同时满足,页面才会是浏览器意义上的 "cross-origin isolated"。这是启用线程的 Web 构建的硬性要求:EditorExportPlatformWeb.xml 中variant/thread_support的说明指出,开启线程需要 "a 'cross-origin isolated' website,setup 可能比较繁琐,并且受安全限制(例如不能与第三方网站通信)";关闭线程则不需要它,但也更容易出现性能和音频问题。
注意Access-Control-Allow-Origin: *是宽松的全开 CORS 头,它只适合本地预览场景,不要照搬到对外部署的服务器配置。
在浏览器里验证响应头
打开导出页面的开发者工具,切到 Network 面板,任选一个已加载的请求查看 Response Headers,应能看到上面三个头。这直接对应serve.py发送的 header 名,也是 PWA 服务 worker 校验时使用的同一组键。
与 PWA 的ensure_cross_origin_isolation_headers选项对照
Godot 的 Web 导出还有一个 PWA 选项progressive_web_app/ensure_cross_origin_isolation_headers(见 EditorExportPlatformWeb.xml):开启后导出的 PWA "will make sure that each request has cross-origin isolation headers (COEP/COOP). This can simplify the setup to serve the exported game."
它的实现是 misc/dist/html/service-worker.js 中的ensureCrossOriginIsolationHeaders():对每个响应检查Cross-Origin-Embedder-Policy是否为require-corp且Cross-Origin-Opener-Policy是否为same-origin,缺哪个补哪个。也就是说:
- 本地用
serve.py预览时,头已经由服务器加好了,service worker 里的检查会直接命中"已有正确头"的分支原样返回; - 部署到不会自己加 COOP/COEP 头的静态托管上时,靠 PWA 的 service worker 兜底补齐(这是该选项存在的目的)。
两者的头取值完全一致,serve.py相当于在本地提前模拟了这套隔离环境。
限制
serve.py是纯预览工具,不提供构建、签名或部署能力;线上部署仍要让自己的服务器(或 PWA 选项)负责 COOP/COEP。- 线程构建依赖的 cross-origin isolated 环境本身有安全代价(见上文
variant/thread_support说明),本地预览同样适用这一限制。 - 端口被占用时换一个
-p端口即可;导出文件不在bin/时务必用-r指定,否则浏览器只会看到空的根目录。
【免费下载链接】godotGodot Engine – Multi-platform 2D and 3D game engine项目地址: https://gitcode.com/GitHub_Trending/go/godot
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考