Angular 4应用部署在Node.js子目录时遇SyntaxError错误求助
这个错误其实挺常见的,根源是浏览器请求Angular的静态资源(比如JS、CSS、assets里的文件)时,服务器没有正确返回对应的文件,反而返回了index.html的内容——浏览器本来要解析JS,结果拿到的是开头为<的HTML,自然就报SyntaxError: expected expression, got '<'了。
你现在只处理了/admin这个路由,但Angular应用加载时,会请求类似/admin/main.js、/admin/styles.css或者/admin/assets/logo.png这类资源,这些请求你的Node服务器没有匹配到对应的处理逻辑,就可能默认返回index.html(或者404,但如果服务器有兜底返回index.html的逻辑,就会出现这个问题)。
下面是具体的修复步骤:
1. 正确托管/admin目录下的静态资源
首先要用Express的express.static中间件来托管admin目录下的所有静态文件,这样浏览器请求这些资源时,服务器能正确返回对应的文件。
修改你的server.js,添加这一行(要在你定义路由之前):
app.use('/admin', express.static(path.join(__dirname, 'admin')));
2. 处理/admin路由的SPA fallback
因为Angular是单页应用,当用户直接访问/admin或者刷新页面时,需要返回index.html。不过注意,上面的静态资源中间件已经能处理存在的文件请求,所以我们需要一个兜底的路由,当请求的资源不存在时,返回index.html。
可以把原来的app.get('/admin', ...)改成更通用的路由:
app.get('/admin/*', (req, res) => { res.sendFile(path.join(__dirname, 'admin/index.html')); });
完整的示例代码片段
把这些整合到你的server.js里,大概是这样:
const express = require('express'); const path = require('path'); const app = express(); // 托管admin目录的静态资源,路径前缀是/admin app.use('/admin', express.static(path.join(__dirname, 'admin'))); // 处理/admin下的所有SPA路由,返回index.html app.get('/admin/*', (req, res) => { res.sendFile(path.join(__dirname, 'admin/index.html')); }); // 其他路由和服务器启动逻辑 app.listen(3020, () => { console.log('Server running on http://localhost:3020'); });
为什么这样能解决问题?
express.static会自动匹配/admin开头的请求,去admin目录里找对应的文件,如果找到就返回,找不到就继续往下走路由。app.get('/admin/*', ...)作为兜底,当静态资源中间件找不到文件时(比如用户访问/admin/dashboard这种Angular路由),就返回index.html,让Angular的路由去处理,同时也确保直接访问/admin时能正确加载index.html。
这样修改后,你再访问http://localhost:3020/admin,Angular的静态资源就能正确加载,不会再出现那个语法错误了。
内容的提问来源于stack exchange,提问作者Joshua Majebi

