Express节点作为启用pushState的服务器提供没有任何path前缀的任何静态资源

我正在用Ember.js或Backbone.js作为前端MVC,express.js(node.js)作为后端服务器构build单页Web应用程序。

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 -- 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) 

当我将任何静态资源定义为相对path时,它将在页面刷新上与根url和硬url进行匹配的path上工作,它为资源提供服务

 GET /assets/styles/reset.css 304 1ms GET /assets/styles/base.css 304 2ms 

但是当我到localhost:3000/users/1并刷新页面,我得到了错误的资源url,所以加载client/index.html失败,因为没有资源在该path。

 GET /users/assets/styles/reset.css 304 2ms GET /users/assets/styles/base.css 304 6ms 

然后,我切换到绝对path在客户端/ index.html (示例代码)

 <link rel="stylesheet" href="/assets/styles/reset.css"> <link rel="stylesheet" href="/assets/styles/base.css"> 

即使在dynamic片段url localhost:3000/users/1 ,所有的资源都在正确的urlpath中。 但是我在前端mvc模板中有一个html img标签,当应用程序启动时将会呈现前端mvc模板。 当我加载页面刷新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"> )中的绝对path和相对path,不pipe用什么方式加载users前缀。

我find了tbranyen的解决scheme,但对我来说并不合适。 我根本不需要设置任何群集,我想要的是我的快递服务器在任何dynamic段匹配时为任何资源提供没有任何前缀。 所以我编写了这个中间件,它启动正确,但仍然加载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进行处理,即使使用dynamic查询段也是如此。 目前,每当url查询涉及到dynamic查询segment /users/:user_id ,来自express服务器的响应将以users前缀为前缀到所有静态资源。

例如,当我加载dynamic段localhost:3000/users/1的url。 如果我有一个资源assets/images/icons/star.pngassets/images/icons/star.png模板中,表示服务器回应/users/assets/images/icons/star.png ,但我没有资产的users文件夹。 我想要回应/assets/images/icons/star.png

我尝试使用绝对path/assets/images/icons/star.png或相对pathassets/images/icons/star.pngassets/images/icons/star.png模板,它总是返回与users前缀的响应。

谢谢你的帮助!

在基本模板的<head>中,将其添加到顶部:

 <base href="/">