【问题标题】:"net::ERR_ABORTED 404" error in a NodeJS app running on Nginx在 Nginx 上运行的 NodeJS 应用程序中出现“net::ERR_ABORTED 404”错误
【发布时间】:2022-06-12 12:08:10
【问题描述】:

我有一个 SPA 面临这个错误,我似乎无法弄清楚为什么我会收到它。

吼,我的 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');
});

这里是nginx.conf的相关部分

upstream strapiClient {
    server botboutique.com.br:3847;
}

这里,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";
    }

在这里,我的 ..views/partials/hearders.conf 中的 HTML 标头部分

<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>

我在 ..views/partials/partials 中的 scripts.ejs:

<!-- 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>

这是我的文件结构:

可以通过botboutique.com.br/strapiClient访问呈现的页面

奇怪的事情:虽然 Edge 和 Firefox 在控制台中显示预期的 URL(botboutique.com.br/strapiClient/some-directory/some-file),但 Goolge Chrome 会从 URL 中抑制“strapiCLient”)。

最后一件事:我正面临"Refused to apply style from '&lt;URL&gt;' because its MIME type ('text/html') is not a supported stylesheet MIME type, and strict MIME checking is enabled.",但我认为我必须先纠正 404 错误,然后再进行此操作...

我的 /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;

【问题讨论】:

  • 使用app.use(express.static(__dirname + '/public'/)); 而不是app.use(express.static('./public/'));

标签: javascript node.js nginx ejs


【解决方案1】:

当您在 URI 前缀下提供 Web 应用程序而不是某种 API 端点时,通常您应该选择

location /prefix/ {
    ...
}

而不是

location /prefix {
    ...
}

您可能认为这两者应该没有显着差异;但是,差异非常显着——在这两种情况下,打开的页面将具有不同的browsing context。当您使用/strapiClient URI 打开页面时,您的浏览上下文为/,而当您使用/strapiClient/ URI 打开页面时,您的浏览上下文为/strapiClient/。决定如何处理相对链接的是浏览上下文——将是来自&lt;script type="text/javascript" src="js/scripto.js"&gt; 标记的脚本,请求为/js/scripto.js/strapiClient/js/scripto.js。我现在无法检查 Edge 或 Firefox;但是,使用谷歌浏览器时,您的资产请求会有所不同,使用带有和不带有斜杠的不同前缀。

使用location /prefix/ { ... } 样式有以下优点:

  • 当其他路由以相同前缀开头时,您永远不会遇到这种情况,例如/prefixed 将被错误的位置处理;

  • 所有使用相对链接引用的资产在被请求时都会自动得到正确的/prefix/

  • 您可以使用自动替换 proxy_pass 指令功能轻松地从代理 URI 中删除 /prefix,因为它的声明包含 URI 部分(此处的尾部斜杠是 URI 部分):

    location /prefix/ {
        proxy_pass http://upstream/;
    }
    

    proxy_pass 指令 documentation 中描述了此行为:

    如果 proxy_pass 指令使用 URI 指定,则当请求传递到服务器时,与位置匹配的规范化请求 URI 部分将替换为指令中指定的 URI:

    location /name/ {
        proxy_pass http://127.0.0.1/remote/;
    }
    
  • 大部分情况下,从/prefix/prefix/的重定向会由nginx自己自动发出;此行为在location 指令documentation 中进行了描述:

    如果位置由以斜杠字符结尾的前缀字符串定义,并且请求由proxy_passfastcgi_passuwsgi_passscgi_passmemcached_passgrpc_pass 之一处理,然后进行特殊处理。为了响应 URI 等于此字符串但没有尾部斜杠的请求,将返回带有代码 301 的永久重定向到附加斜杠的请求 URI。

不幸的是,我不确定应该如何更改 express.static 中间件函数。英文文档页面suggests如下做法:

app.use('/static', express.static(path.join(__dirname, 'public')))

上述文档页面的俄语翻译提出了不同的建议:

app.use('/static', express.static(__dirname + '/public'));

或者你应该直接定义你的 URI 前缀:

app.use('/static', express.static('/strapiClient/public'));

尽管如此,我希望这至少能部分回答您的一些问题,并为您提供一些起点,让您了解从何处开始调试您的应用和表达静态模块行为。

【讨论】:

  • 非常感谢您澄清浏览器上下文,您的提示修复了 URL 上的不一致 - 现在所有浏览器都显示正确的 URL。静态问题仍然存在,我正试图弄清楚如何调试,因为 Nodemon 在它的控制台中没有显示任何内容。
  • 当您设法修复您的 express.static 中间件时,也请在此处发布解决方案,这可能对其他尝试在 URI 前缀下提供此类 Web 应用程序的人有所帮助。跨度>
  • console.log('Root directory: ' + __dirname); 给了我/home/webmaster/apps/strapiClient
  • console.log(app.use('/static', express.static(path.join(__dirname + '/public')))); 给了我很多东西,但我注意响应的最后一部分:mountpath: '/', 现在我要试着理解为什么不 mountpath: '/strapiClient',
【解决方案2】:

正如@Ivan Shatsky 所指出的,请确保浏览器上下文:了解如何提供相关链接非常重要。在我的场景中,我在location /strapiClient/ 的末尾添加了一个额外的斜杠,它使一切正常。因此,etc/nginx/sites-enabled/00-default.ssl.conf 是我编辑以解析上下文并正确找到文件的唯一文件。

不幸的是,出于某种我不理解的原因,NodeJS 拒绝使用express.staticserver.js 提供页面。对我有用的解决方案非常冗长,似乎是一种“蛮力”方法:

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

尽管I'm still struggling with how NodeJS is serving the pages,这个问题已经解决了。再次感谢@Ivan。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-08-02
    • 2014-04-24
    • 2018-06-06
    • 2019-12-10
    • 1970-01-01
    • 1970-01-01
    • 2022-01-06
    • 1970-01-01
    相关资源
    最近更新 更多