Zig静态文件服务器无法加载JS文件,请求排查修复
Zig静态文件服务器无法加载JavaScript文件的解决方案
当前用Zig实现的静态文件服务器可正常加载index.html,但无法加载main.js,浏览器报错:
unexpected
</at<script src="main.js"></script>
问题根源
现有代码存在两处关键问题:
- 路由逻辑错误:只要请求路径以
/开头,就固定返回index.html——包括请求/main.js时,服务器返回的是HTML内容而非JS文件,浏览器将HTML当作JavaScript解析,触发语法错误。 - MIME类型缺失:未为不同类型文件设置对应
Content-Type响应头,即便正确返回文件,浏览器也无法识别类型。
修改方案
1. 添加MIME类型映射函数
在代码中新增一个根据文件扩展名返回对应MIME类型的工具函数(可放在readFile函数前后任意位置):
fn getMimeType(filename: []const u8) []const u8 { if (std.fs.path.extension(filename)) |ext| { if (std.mem.eql(u8, ext, ".html")) return "text/html; charset=utf-8"; if (std.mem.eql(u8, ext, ".js")) return "application/javascript; charset=utf-8"; // 可按需扩展更多文件类型的MIME映射 if (std.mem.eql(u8, ext, ".css")) return "text/css; charset=utf-8"; if (std.mem.eql(u8, ext, ".png")) return "image/png"; if (std.mem.eql(u8, ext, ".jpg")) return "image/jpeg"; } // 默认返回二进制文件类型 return "application/octet-stream"; }
2. 重写请求处理逻辑
修改handleRequest函数,实现动态路由匹配、文件读取及MIME类型设置:
fn handleRequest(response: *http.Server.Response, allocator: std.mem.Allocator) !void { log.info("{s} {s} {s}", .{ @tagName(response.request.method), @tagName(response.request.version), response.request.target }); const body = try response.reader().readAllAlloc(allocator, 8192); defer allocator.free(body); if (response.request.headers.contains("connection")) { try response.headers.append("connection", "keep-alive"); } // 根路径请求默认返回index.html var target_path = response.request.target; if (std.mem.eql(u8, target_path, "/")) { target_path = "/index.html"; } // 转换为本地文件路径,同时防止路径遍历攻击 const filename = target_path[1..]; if (std.mem.indexOf(u8, filename, "..") != null) { response.status = .forbidden; try response.do(); return; } // 尝试读取目标文件,处理文件不存在的情况 const contents = readFile(allocator, filename) catch |err| switch (err) { error.FileNotFound => { response.status = .not_found; try response.do(); return; }, else => return err, }; defer allocator.free(contents); // 设置正确的Content-Type并返回文件内容 const mime_type = getMimeType(filename); response.transfer_encoding = .chunked; try response.headers.append("content-type", mime_type); try response.do(); if (response.request.method != .HEAD) { try response.writeAll(contents); try response.finish(); } }
关键优化点
- 路径安全:新增对
..的检测,避免攻击者通过路径遍历访问服务器敏感文件 - 动态路由:根据请求路径返回对应文件,根路径自动映射到
index.html - 正确MIME类型:浏览器可根据响应头识别文件类型,确保JS、CSS等资源正常解析
内容的提问来源于stack exchange,提问作者Hasan A Yousef
相关产品推荐
相关产品推荐

