Logan MacDougall
Logan MacDougall

Reputation: 149

how to display webpages from multiple different directories using express

I'm trying to run a few different sites on an ubuntu server which I'm connected to via a public connection. There's supposed to be a main site and 2 sub-sites. Currently, the important part of the directory is laid out as follows:

.
|---index.js
|--_node_modules
   └---(all the node modules)
|---package-lock.json
|--_Public
   |---index.html
   └---(required folders & files for index.html)
|--_A
   └--_folder
      |---index.html
      └---(required folders & files for index.html)
|--_B
   └--_folder
      |---index.html
      └---(required folders & files for index.html)

My index.js has the following code:

const express = require('express')
const path = require('path')
const app = express()
const port = 3000

app.get('/', (req, res) => {
        app.use(express.static(path.resolve('/public')))
        res.sendFile('index.html')
})

app.get('/a', (req, res) => {
        app.use(express.static(path.resovle('/A/folder')))
        res.sendFile('index.html')
})

app.get('/b', (req, res) => {
        app.use(express.static(path.resolve('/B/folder')))
        res.sendFile('index.html')
})

app.listen(port, () => {
        console.log('Running server on port ' + port)
})

With this way of implementing index.js, none of the sites work at all.

When I type "(public_ip):3000", "(public_ip):3000/a" or "(public_ip):3000/b" it gives me:

Error: ENOENT: no such file or directory, stat '/index.html'


I also tried my index.js as the following:

const express = require('express')
const path = require('path')
const app = express()
const port = 3000

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

app.get('/', (req, res) => {
        res.sendFile('/index.html')
})

app.get('/a', (req, res) => {
        res.sendFile('/index.html', {root: 'A/folder'})
})

app.get('/b', (req, res) => {
        res.sendFile('/index.html', {root: 'B/folder'})
})

app.listen(port, () => {
        console.log('Running server on port ' + port)
})

This will result in "(public_ip):3000" working perfectly. The only issue from here is that now "(public_ip):3000/a" and "(public_ip):3000/b" only rendered the html and can't find any of the other files, with the following errors in the console:

Refused to apply style from '<URL>' because its MIME type ('text/html') is not a supported stylesheet 
MIME type, and strict MIME checking is enabled.
a:1 Refused to apply style from 'http://(public ip):3000/A/folder/css/animate.css' because its MIME type ('text/html') is not a supported stylesheet MIME type, and strict MIME checking is enabled.
a:1 Refused to apply style from 'http://(public ip):3000/A/folder/css/icomoon.css' because its MIME type ('text/html') is not a supported stylesheet MIME type, and strict MIME checking is enabled.
a:1 Refused to apply style from 'http://(public ip):3000/A/folder/css/bootstrap.css' because its MIME type ('text/html') is not a supported stylesheet MIME type, and strict MIME checking is enabled.
a:1 Refused to apply style from 'http://(public ip):3000/A/folder/css/flexslider.css' because its MIME type ('text/html') is not a supported stylesheet MIME type, and strict MIME checking is enabled.
a:1 Refused to apply style from 'http://(public ip):3000/A/folder/css/owl.carousel.min.css' because its MIME type ('text/html') is not a supported stylesheet MIME type, and strict MIME checking is enabled.
a:1 Refused to apply style from 'http://(public ip):3000/A/folder/css/owl.theme.default.min.css' because its MIME type ('text/html') is not a supported stylesheet MIME type, and strict MIME checking is enabled.
a:1 Refused to apply style from 'http://(public ip):3000/A/folder/css/style.css' because its MIME type ('text/html') is not a supported stylesheet MIME type, and strict MIME checking is enabled.
a:1 Refused to apply style from 'http://(public ip):3000/vendor/bootstrap/css/bootstrap.min.css' because its MIME type ('text/html') is not a supported stylesheet MIME type, and strict MIME checking is enabled.
a:1 Refused to apply style from 'http://(public ip):3000/vendor/fontawesome-free/css/all.min.css' because its MIME type ('text/html') is not a supported stylesheet MIME type, and strict MIME checking is enabled.
a:1 Refused to apply style from 'http://(public ip):3000/css/resume.css' because its MIME type ('text/html') is not a supported stylesheet MIME type, and strict MIME checking is enabled.
a:1 Refused to apply style from 'http://(public ip):3000/css/font-mfizz.css' because its MIME type ('text/html') is not a supported stylesheet MIME type, and strict MIME checking is enabled.
a:1 Refused to apply style from 'http://(public ip):3000/vendor/bootstrap/css/bootstrap.min.css' because its MIME type ('text/html') is not a supported stylesheet MIME type, and strict MIME checking is enabled.
a:1 Refused to apply style from 'http://(public ip):3000/css/resume.css' because its MIME type ('text/html') is not a supported stylesheet MIME type, and strict MIME checking is enabled.
a:1 Refused to apply style from 'http://(public ip):3000/css/font-mfizz.css' because its MIME type ('text/html') is not a supported stylesheet MIME type, and strict MIME checking is enabled.
a:1 Refused to apply style from 'http://(public ip):3000/vendor/fontawesome-free/css/all.min.css' because its MIME type ('text/html') is not a supported stylesheet MIME type, and strict MIME checking is enabled.
a:46 GET http://(public ip):3000/js/modernizr-2.6.2.min.js net::ERR_ABORTED 404 (Not Found)
a:864 GET http://(public ip):3000/js/jquery.flexslider-min.js net::ERR_ABORTED 404 (Not Found)
a:868 GET http://(public ip):3000/js/jquery.countTo.js net::ERR_ABORTED 404 (Not Found)
a:871 GET http://(public ip):3000/js/portfolio.js net::ERR_ABORTED 404 (Not Found)
2a:1 GET http://(public ip):3000/images/aboutme.jpg 404 (Not Found)
DevTools failed to load SourceMap: Could not load content for http://(public ip):3000/js/bootstrap.min.js.map: HTTP error: status code 404, net::ERR_HTTP_RESPONSE_CODE_FAILURE
a:864 GET http://(public ip):3000/js/jquery.flexslider-min.js net::ERR_ABORTED 404 (Not Found)
a:868 GET http://(public ip):3000/js/jquery.countTo.js net::ERR_ABORTED 404 (Not Found)
main.js:6 Uncaught TypeError: $(...).stellar is not a function
    at main.js:6
    at main.js:245
(anonymous) @ main.js:6
(anonymous) @ main.js:245
a:871 GET http://(public ip):3000/js/portfolio.js net::ERR_ABORTED 404 (Not Found)

As you can see in the error, I set some of my html links and scripts with the path from the index.js file (ex: A/folder/css/animate.css) and the rest from the index.html file (ex: js/modernizr-2.6.2.min.js).

It seems neither of these worked so I don't know what else to try. Hopefully this is all the information for someone to know what the issue is. If not, I'm sure you'll let me know. Thank you.

Upvotes: 0

Views: 56

Answers (1)

Lin Du
Lin Du

Reputation: 102207

You should use multiple static assets directories, call the express.static middleware function multiple times. Besides, we can create a virtual path prefix (where the path does not actually exist in the file system) for files that are served by the express.static function, specify a mount path for the static directory. We use virtual path prefix to distinguish different folders(A,B,public).

const express = require('express');
const path = require('path');
const app = express();
const port = 3000;

app.use(express.static(path.resolve(__dirname, './public')));
app.use('/a', express.static(path.resolve(__dirname, './A/folder')));
app.use('/b', express.static(path.resolve(__dirname, './B/folder')));

app.get('/', (req, res) => {
  res.sendFile('index.html', { root: path.resolve(__dirname, 'public') });
});

app.get('/a', (req, res) => {
  res.sendFile('index.html', { root: path.resolve(__dirname, 'A/folder') });
});

app.get('/b', (req, res) => {
  res.sendFile('index.html', { root: path.resolve(__dirname, 'B/folder') });
});

app.listen(port, () => {
  console.log('Running server on port ' + port);
});

A/folder/index.html:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="/a/css/style.css">
  <title>A</title>
</head>
<body>
  A
</body>
</html>

A/folder/css/style.css:

body {
  background: red;
}

The files in the B directory are the same as the A directory.

public/index.html:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <link rel="stylesheet" href="/css/resume.css">
  <title>Document</title>
</head>
<body>
  From public
</body>
</html>

public/css/resume.css:

body {
  background-color: yellow;
}

source code: https://github.com/mrdulin/expressjs-research/tree/master/src/stackoverflow/65398400

Upvotes: 1

Related Questions