Node.js Express服务运行时前端JS无法访问同目录CSV文件报错排查
问题原因
直接本地打开HTML文件时走file协议,浏览器直接读取本地磁盘同目录下的文件,不需要服务端参与,所以可以正常加载data.csv。启动Node服务后走HTTP协议,所有前端请求的资源都需要Express服务配置对应的响应规则,当前代码存在两个核心问题导致报错:
- 路由配置完全错误:你将服务端本地磁盘绝对路径(
__dirname + '/xxx.html')直接作为HTTP请求的路由匹配规则,同时301跳转的Location响应头也写了本地绝对路径,导致浏览器会发起/Users/danzam284/Desktop/DailyTracker-main/xxx格式的异常请求,服务端自然没有对应路由可以响应。 - 未配置静态资源托管:Express默认不会对外开放服务端本地的任意文件访问权限,即便路由正确,data.csv这类静态文件也需要手动配置静态目录规则,服务端才会响应对应的请求。
修复方案
- 修正所有路由和301跳转配置
删除所有路由路径里的__dirname前缀,路由只匹配web访问路径;所有301跳转的地址改成根路径开头的web相对路径,不要带本地磁盘路径。
修正后的路由示例:
// 首页路由保持原有写法即可 app.get('/', (req, res) => { res.sendFile(__dirname + '/login.html'); }); // 其余页面路由删掉路径里的__dirname app.get('/index.html', (req, res) => { res.sendFile(__dirname + '/index.html'); }); app.get('/complete.html', (req, res) => { res.sendFile(__dirname + '/complete.html'); }); app.get('/results.html', (req, res) => { res.sendFile(__dirname + '/results.html'); });
所有301跳转的响应头修改为对应web路径:
// 登录后跳转 res.writeHead(301, {"Location": "/index.html"}); // 提交饮水数据后跳转 res.writeHead(301, {"Location": "/complete.html"}); // 完成后跳转结果页 res.writeHead(301, {"Location": "/results.html"});
- 添加静态资源托管配置
在初始化express实例后,立刻添加静态资源中间件,将项目根目录设置为静态资源目录,这样data.csv以及其他本地静态文件都可以被前端正常请求:
const app = express(); // 新增这行配置 app.use(express.static(__dirname)); // 后续再配置bodyParser、其他业务路由 var urlencodedParser = bodyParser.urlencoded({ extended: false });
- 修复异步时序问题
当前写CSV文件的逻辑是异步回调,可能出现文件还没写入完成就跳转到结果页,导致前端请求data.csv时文件还不存在的问题。将parseData里的文件写入改为await调用的promise写法,保证文件写完再跳转:
async function parseData() { const csv = await findCommon(); // 改用promise版本的writeFile配合await await fs.writeFile(__dirname + '/data.csv', csv); }
内容的提问来源于stack exchange,提问作者Daniel Zamloot
相关产品推荐
相关产品推荐

