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;
CodePudding user response:
When you serve a web app rather than some kind of API endpoint under an URI prefix, generally you should choose
location /prefix/ {
...
}
rather than
location /prefix {
...
}
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):location /prefix/ { proxy_pass http://upstream/; }
This behavior is described in the
proxy_pass
directive documentation:If the
proxy_pass
directive is specified with a URI, then when a request is passed to the server, the part of a normalized request URI matching the location is replaced by a URI specified in the directive:location /name/ { proxy_pass http://127.0.0.1/remote/; }
The redirection from
/prefix
to/prefix/
will be automatically issued by nginx itself in most cases; this behavior is described in thelocation
directive documentation:If a location is defined by a prefix string that ends with the slash character, and requests are processed by one of
proxy_pass
,fastcgi_pass
,uwsgi_pass
,scgi_pass
,memcached_pass
, orgrpc_pass
, then the special processing is performed. In response to a request with URI equal to this string, but without the trailing slash, a permanent redirect with the code 301 will be returned to the requested URI with the slash appended.
Unfortunately I don't know for sure how you should change your express.static
middleware function. An English documentation page suggests the following approach:
app.use('/static', express.static(path.join(__dirname, 'public')))
Russian translation of the aforementioned documentation page suggests a different one:
app.use('/static', express.static(__dirname '/public'));
Or maybe you should define your URI prefix directly:
app.use('/static', express.static('/strapiClient/public'));
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.
CodePudding user response:
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
at server.js
. And the solution that worked for me is quite verbose and seems like a "brute force" approach:
app.use('*/images', express.static(path.join(__dirname '/public/images')));
app.use('*/js', express.static(path.join(__dirname '/public/js')));
app.use('*/css', express.static(path.join(__dirname '/public/css')));
app.use('*/slick-1.8.1', express.static(path.join(__dirname '/public/slick-1.8.1')));
Despite I'm still struggling with how NodeJS is serving the pages, this question is solved. Thanks again @Ivan.