简体   繁体   中英

How to include JS, CSS and other server-side utils to a HTML page in NodeJs using expressJs?

I could not find any solutions that worked for me.

I am trying to create a simple microservices architecture with Node.js instances. I do not use Dockerfile. The homepage microservices displays correctly the html with CSS, JS. The gateway microservice does not load the CSS, JS (the page looks broken).

homepage html here

gateway response html here

At the moment I have 2 microservices:

  1. Express server that sends index.html as file. It loads correctly the page with assets (css, images, javascript). I have used app.use(express.static('public')) .

homepage:

const express = require('express')
const app     = express()
var path      = require("path")

app.use(express.static('public'))

app.get('/', (req, res) => {

    res.sendFile(path.join(__dirname+'/public/index.html'));
})

app.listen(3001, () => console.log('Homepage listening on port 3001!'))
  1. Express server that receives requests and wants to deliver content to user. I am trying to create an API Gateway to filter traffic (on authentication for example) and write logs.

gateway:

const express = require('express')
const request = require('request-promise-native')
const app = express()

app.get('/', async (req, res) => {
    // Write logs in database
    const uri = "http://localhost:3001/"
    const result = await request(uri)
    res.send(result)
 })

 app.listen(3000, () => console.log('Public API Gateway listening on port 3000!'))

Project structure with the 2 server files here

Any solution is really appreciated.

Thanks!

You need to make your JavaScript, CSS and images be available for public use as all our files are hidden from client-side.

So What to do? Just keep all your client-side JavaScript, CSS and image in public folder and make that public folder available for client-side like:

//Using expressJs
//All your HTML will be in this folder.
app.set('views', __dirname + '/views');
//This is your HTML template to know more [what is ejs][1] and what's different between html and ejs or jade please do little research.
app.set('view engine', 'ejs');

//This is what makes your image, JS and CSS available to HTML page.
app.use(express.static(path.join(__dirname, 'public'))); 

How to import files from public folder? Use following ways:

// location of all these files is in public folder like:
// public/min/css/bootstrap.min.css
// public/min/js/app.min.js
// public/images/image1.jpg
<link rel="stylesheet" type="text/css" href="/min/css/bootstrap.min.css" />
<script type="text/javascript" src="/min/js/app.min.js"></script>

When you request the homepage from the homepage microservice and serve its html to the gateway microservice, all resources (ie styles, scripts and images) aren't loaded correctly. That's because in your index.html relative paths to resources are used, for eg

<link href="assets/styles.css"/>

so:

  • In homepage microservice, assets/styles.css gets resolved to //localhost:3001/assets/styles.css , then express server serves assets/styles.css from public directory since express is configured to serve static files from the public directory:

    app.use(express.static('public'))

  • In gateway microservice, assets/styles.css gets resolved to //localhost:3000/assets/styles.css , then express server tries to serve assets/styles.css but returns an error because the express server in the gateway microservice isn't configured to serve static assets from any directory.

A simple solution to this problem is to redirect all the calls to the /assets in the gateway microservice to //localhost:3001/assets , so server.js in your gateway will look like this

const express = require('express');
const request = require('request-promise-native');
const app = express();

// redirect /assets to localhost:3001/assets
app.get('/assets/**', (req, res) => {
    const uri = 'http://localhost:3001' + req.path;
    res.redirect(uri);
});

app.get('/', async (req, res) => {
    // Write logs in database
    const uri = "http://localhost:3001/";
    const result = await request(uri);
    res.send(result);
});

app.listen(3000, () => console.log('Public API Gateway listening on port 3000!'));

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM