I have an SPA facing this error and I cannot seem to figure out why I am receiving it.
Bellow, my server.js
// Load Node modules
var express = require('express');
const bodyParser = require('body-parser');
const path = require('path');
const ejs = require('ejs');
var falaUser = require("./routes/falaUser");
//Config files
process.env['NODE_CONFIG_DIR'] = __dirname + '/config/';
console.log("Usando "+process.env['NODE_CONFIG_DIR'] +" como diretório de configurações");
var config = require("config");
// Initialise Express
var app = express();
// Render static files
app.use(express.static('./public/'));
app.use(bodyParser.json());
app.use("/falauser", falaUser);
// Set the view engine to ejs
app.set('view engine', 'ejs');
var server = app.listen(config.get("port"), config.get("hostname"), function () {
var host = server.address().address;
var port = server.address().port;
console.log('Rodando bacana em https://' + host + ':' + port)
});
// Root Route
app.get('/strapiClient', function (req, res) {
res.render('pages/index');
});
Here, relevant part of nginx.conf
upstream strapiClient {
server botboutique.com.br:3847;
}
Here, relevant part of nginx/sites-enabled/00-default.ssl.conf
# strapiClient
location /strapiClient {
root html;
index index.html index.htm index.ejs;
proxy_read_timeout 120;
proxy_pass http://strapiClient;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_set_header Host $http_host;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
}
Here, my HTML header partials in my ..views/partials/hearders.conf
<header>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>BOTIKE - Robôsitos que conversam com pessoas e negócios</title>
<link rel="icon" href="images/cropped-favicon_botike-192x192.png" />
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/font-awesome/4.7.0/css/font-awesome.min.css" integrity="sha384-wvfXpqpZZVQGK6TAh5PVlGOfQNHSoD2xbE+QkPxCAFlNEevoEH3Sl0sibVcOQVnN" crossorigin="anonymous">
<link rel="preconnect" href="https://fonts.gstatic.com">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Roboto:wght@500;900&display=swap">
<link rel="preconnect" href="https://fonts.gstatic.com">
<link rel="stylesheet" href="https://fonts.googleapis.com/css2?family=Roboto+Condensed:wght@400;700;900&display=swap">
<!-- Bootstrap -->
<link type="text/css" rel="stylesheet" href="css/bootstrap-4.4.1.css">
<!-- Animação dos balões da capa -->
<link type="text/css" rel="stylesheet" href="css/animation-icoHum.css">
<link type="text/css" rel="stylesheet" href="css/animation-icoBot.css">
<link type="text/css" rel="stylesheet" href="css/animation-lettering.css">
<link type="text/css" rel="stylesheet" href="css/style.css">
<link type="text/css" rel="stylesheet" href="css/stilo.css">
<link type="text/css" rel="stylesheet" href="slick-1.8.1/slick/slick.css">
<link type="text/css" rel="stylesheet" href="slick-1.8.1/slick/slick-theme.css">
<!-- Script principal -->
<script type="text/javascript" src="js/scripto.js"></script>
</header>
My scripts.ejs in ..views/partials/partials:
<!-- jQuery (necessary for Bootstrap's JavaScript plugins) -->
<script type="text/javascript" src="js/jquery-3.4.1.min.js "></script>
<!-- Include all compiled plugins (below), or include individual files as needed -->
<script type="text/javascript" src="js/popper.min.js "></script>
<script type="text/javascript" src="js/bootstrap-4.4.1.js "></script>
<script type="text/javascript" src="slick-1.8.1/slick/slick.min.js"></script>
<script type="text/javascript" src="js/script.js "></script>
That´s my files structure:
The rendered page can acessed at botboutique.com.br/strapiClient
A weird thing: while Edge and Firefox shows in the console the expected URL (botboutique.com.br/strapiClient/some-directory/some-file), Goolge Chrome supress "strapiCLient" from the URL).
A final thing: I’m facing a "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."
but I think that I must to correct 404 error first before going into this…
My /etc/nginx/conf-available:
add_header X-Frame-Options sameorigin;
add_header X-Content-Type-Options nosniff;
add_header X-XSS-Protection '1; mode=block';
add_header X-Download-Options noopen;
add_header X-Permitted-Cross-Domain-Policies none;
add_header Content-Security-Policy "default-src https: data: wss: 'unsafe-inline' 'unsafe-eval'";
add_header Referrer-Policy strict-origin;
2
Answers
As @Ivan Shatsky pointed, be sure about browser context: that's prety important to understand how relative links will be served. In my scenario, I put an extra slash at the end of
location /strapiClient/
and it makes everything work. So,etc/nginx/sites-enabled/00-default.ssl.conf
was the only file that I edit to resolve the context and find the files correctly.Unfortunatelly and for some reason that I didn't understand (yet) NodeJS refused to serve the pages using
express.static
atserver.js
. And the solution that worked for me is quite verbose and seems like a "brute force" approach:Despite I'm still struggling with how NodeJS is serving the pages, this question is solved. Thanks again @Ivan.
When you serve a web app rather than some kind of API endpoint under an URI prefix, generally you should choose
rather than
You may think there should no significant difference in those two; however, the difference is more than significant – the opened page will have different browsing context in those two cases. When you open your page using
/strapiClient
URI, your browsing context is/
and when you open your page using/strapiClient/
URI, your browsing context is/strapiClient/
. And it is the browsing context that determines how relative links will be processed – would be the script from the<script type="text/javascript" src="js/scripto.js">
tag requested as/js/scripto.js
or as/strapiClient/js/scripto.js
. I cannot check Edge or Firefox right now; however, using Google Chrome your assets are being requested differently using different prefixes with and without trailing slash.Using the
location /prefix/ { ... }
style has the following advantages:you’d never face the situation when the other route starting with the same prefix, e.g.
/prefixed
will be handled with the wrong location;all the assets referred using relative links will get correct
/prefix/
automatically when being requested;you can easily strip the
/prefix
from the proxied URI using the autoreplaceproxy_pass
directive feature when it it’s declaration includes an URI part (the trailing slash here is an URI part):This behavior is described in the
proxy_pass
directive documentation:The redirection from
/prefix
to/prefix/
will be automatically issued by nginx itself in most cases; this behavior is described in thelocation
directive documentation:Unfortunately I don’t know for sure how you should change your
express.static
middleware function. An English documentation page suggests the following approach:Russian translation of the aforementioned documentation page suggests a different one:
Or maybe you should define your URI prefix directly:
Nevertheless, I hope this answers some of your questions, at least partially, and gives you some starting point of where to start debugging your app and the express static module behavior.