【发布时间】:2014-07-31 14:47:40
【问题描述】:
我正在构建一个单页 Web 应用程序,其中 Ember.js 或 Backbone.js 作为前端 MVC,express.js(node.js) 作为后端服务器。
server/app.js 代码简述
app.use(bodyParser.json());
app.use(express.static(path.join(__dirname, '..', 'client')));
app.get('*', function(req, res) {
return res.render('base'); (will sendFile (client/index.html) )
});
它将加载所有公共资产的 client/ 文件夹,客户端文件夹结构如下所示
- client
-- index.html ( will be rendered as always )
-- app (front end mvc code)
-- assets
-- images
-- styles
当前端 MVC 启用 html5 pushstate 时,express 服务器也总是为所有匹配的路由提供服务,而当页面刷新或手动 url 时,它会像往常一样呈现 index.html插入到浏览器中。
client/index.html(示例代码)
<link rel="stylesheet" href="assets/styles/reset.css">
<link rel="stylesheet" href="assets/styles/base.css">
以下是三种不同的 URL 案例
localhost:3000/ (root)
localhost:3000/users || localhost:3000/#/users (hard url)
localhost:3000/users/1 || localhost:3000/#/users/1 ( dynamic segment)
当我将任何静态资源定义为相对路径时,它会在页面刷新时将路径与根 url 和硬 url 匹配,它将资源作为
GET /assets/styles/reset.css 304 1ms
GET /assets/styles/base.css 304 2ms
但是当我到达localhost:3000/users/1 并刷新页面时,我得到了错误的资源url,因此加载client/index.html 失败,因为该路径中没有资源。
GET /users/assets/styles/reset.css 304 2ms
GET /users/assets/styles/base.css 304 6ms
然后我切换到绝对路径 client/index.html(示例代码)
<link rel="stylesheet" href="/assets/styles/reset.css">
<link rel="stylesheet" href="/assets/styles/base.css">
即使在动态段 url localhost:3000/users/1 中也能正常工作,所有资源都在正确的 url 路径中服务。但我在前端 mvc 模板中有一个 html img 标签 <img src="assets/images/icons/star.png" alt="star">,它将在应用程序启动时呈现。当我在页面刷新时加载 localhost:3000/users/1 时,这就是我得到的
GET /assets/styles/reset.css 304 1ms
GET /assets/styles/base.css 304 2ms
GET /users/assets/images/icons/star.png 304 5ms
我尝试在前端 mvc 模板 (<img src="/assets/images/icons/star.png" alt="star">) 中使用绝对路径和相对路径,无论如何它都会以 users 前缀加载。
我通过tbranyen 找到了一个解决方案,但它对我来说不太奏效。我根本不需要设置任何集群,我想要的是我的快速服务器在匹配任何动态段时为没有任何前缀的任何资源提供服务。所以我写了这个中间件,它触发正确但仍然加载带有users/前缀的静态资源。
// this route uses the ":user" named parameter
// which will cause the 'user' param callback to be triggered
router.get('/users/:user_id', function(req, res, next) {
console.log('req.params: ', req.params.user_id );
//console.log('@TODO: need to handle the params here');
//next();
return res.render('base');
});
问题:
当使用 Express.js 作为服务器时,我希望每个浏览器请求都将使用响应 client/index.html 进行处理,即使使用动态查询段也是如此。目前,每当url查询涉及动态查询段/users/:user_id时,express服务器的响应都会以users为前缀到所有静态资源。
例如,当我加载带有动态段 localhost:3000/users/1 的 url 时。如果我在车把模板中有资源assets/images/icons/star.png,则将服务器响应返回/users/assets/images/icons/star.png,但我没有包含资产的users 文件夹。我想要回复/assets/images/icons/star.png。
我尝试在车把模板中使用绝对路径/assets/images/icons/star.png 或相对路径assets/images/icons/star.png,它总是在响应中以users 前缀返回。
感谢您的帮助!
【问题讨论】:
-
如果您在顶部或底部包含一个 TLDR 部分可能会有所帮助。我找不到它。
-
@JoshWillik 我已经更新了底部的问题。如果您不清楚,请告诉我。谢谢。
标签: node.js backbone.js ember.js express pushstate