Express node worked as pushState enabled server serve any static resource without any path prefix

白昼怎懂夜的黑 提交于 2019-12-10 15:11:54

问题


I am building a single page web application with Ember.js or Backbone.js as front end MVC, express.js(node.js) as back end server.

server/app.js code in short

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

It will load up the client/ folder with all the public assets, client folder structure looks like this

- client
   -- index.html ( will be rendered as always )
   -- app (front end mvc code)
   -- assets
      -- images
      -- styles

When html5 pushstate is enabled by front end MVC, express server is always serving all the matching route as well, which in turn render index.html as always when page is refreshed or url is being manually inserted in the browser.

client/index.html (sample code)

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

Here are three different URLs cases

localhost:3000/        (root)
localhost:3000/users  || localhost:3000/#/users (hard url)
localhost:3000/users/1    || localhost:3000/#/users/1  ( dynamic segment)

When I defined any static resource as relative path, it works on matching path with root url and hard url on page refresh, it serves resources as

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

But when I got to localhost:3000/users/1 and refresh the page, I got the wrong resource url, so it failed on loading client/index.html since there are no resources in that path.

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

Then I switched to absolute path in client/index.html (sample code)

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

it works well even in the dynamic segment url localhost:3000/users/1, all resource serve in the correct url path. but I have an html img tag <img src="assets/images/icons/star.png" alt="star"> in front end mvc template which will be rendered when application boots up. When I load up localhost:3000/users/1 on page refresh, here is what I get

GET /assets/styles/reset.css 304 1ms
GET /assets/styles/base.css 304 2ms
GET /users/assets/images/icons/star.png 304 5ms

I tried with absolute path and relative path in front end mvc template (<img src="/assets/images/icons/star.png" alt="star">), it loads with users prefix no matter what.

I found a solution by tbranyen, but it did not quite work for me. I do not need to setup any cluster at all, what I want is my express server to serve any resource without any prefix when any dynamic segment is being matched. So I wrote this middleware, and it fires correct but still loads the static resource with users/ prefix.

// 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');
});

Problem:

When using Express.js as a server, I want every browser request will be handled with response client/index.html, even with dynamic query segment. Currently, whenever url query involves with dynamic query segment /users/:user_id, the response from express server will prefix with users to all the static resources.

For example, when I load the url with dynamic segment localhost:3000/users/1. if i have a resources assets/images/icons/star.png in handlebars template, express server response back /users/assets/images/icons/star.png, but I do not have users folder with the assets. What I want response back /assets/images/icons/star.png.

I tried with absolute path /assets/images/icons/star.png or relative path assets/images/icons/star.png in the handlebars template, it always return with users prefix in the response.

Thanks for any help!


回答1:


In the <head> of your base template, add this toward the top:

<base href="/">


来源:https://stackoverflow.com/questions/25062002/express-node-worked-as-pushstate-enabled-server-serve-any-static-resource-withou

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!