Express JS无法与Nginx一起提供静态文件。

5

我很困惑为什么我的最新 Web 应用程序无法获取我所包含的任何 css 或 js 文件。在我的本地机器上,这些文件可以正常传输,但是当我将其托管在我的 nginx 服务器上时,我会收到 404 错误。以下是我的 html 引用:

<!-- ANGULAR -->
<script src="/bower_components/angular/angular.js"></script>

<!-- ANGULAR BOOTSTRAP UI -->
<script src="/bower_components/angular-bootstrap/ui-bootstrap.js"></script>

<!-- ANGULAR ROUTE-->
<script src="/bower_components/angular-route/angular-route.js"></script>

<!-- Bootstrap CSS -->
<link rel="stylesheet" type="text/css" href="./bower_components/bootstrap-css-only/css/bootstrap.css">

<!-- ANGULAR APP SETUP -->
<script src="/js/app.js"></script>
<script src="/js/controllers.js"></script>

<!-- Custom styles -->
<link rel="stylesheet" type="text/css" href="/css/styles.css">

以下是Node.js Express服务器端代码

// set up ========================
var express  = require('express');
var app      = express();                        // create our app w/ express
var morgan = require('morgan');                  // log requests to the console (express4)
var bodyParser = require('body-parser');         // pull information from HTML POST (express4)
var methodOverride = require('method-override'); // simulate DELETE and PUT (express4)
var path = require('path');

// configuration =================

// set the static files location /public/img will be /img for users
app.use(express.static(path.join(__dirname, '/public')));
console.log("DIRECTORY= "+path.join(__dirname, '/public'));

app.use(morgan('dev'));                                         // log every request to the console
app.use(bodyParser.urlencoded({'extended':'true'}));            // parse application/x-www-form-urlencoded
app.use(bodyParser.json());                                     // parse application/json

// application -------------------------------------------------------------
app.get('/', function(req, res) {
    res.sendFile(path.join(__dirname, '/public/index.html')); // load the single view file (angular will handle the page changes on the front-end)
});

app.get('/DI_Uploader/', function(req, res) {
    res.sendFile(path.join(__dirname, '/public/index.html')); // load the single view file (angular will handle the page changes on the front-end)
});

//decides between what heroku would give it or our own chosen port for a locally hosted solution
app.set('port', (process.env.PORT || 8002));

app.listen(app.get('port'), function() {
  console.log('Node app is running on port', app.get('port'));
});

我将所有的js/css/bower_components放在public目录下。唯一我能想到的问题是nginx,我在这里有...

location /DI_Uploader/ {

    proxy_ignore_client_abort on;
    proxy_pass http://webserverName:8002;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;
}

唯一与托管版本和本地版本不同的是,要访问托管版本,我将转到http://website.com/DI_Uploader/而不是根目录 website.com。由于我对express仍然相当陌生,所以任何指导都有帮助。

编辑:删除了html包含项前面的句号。

不知道如何在评论中添加此信息,但以下是Web服务器上的文件夹结构。

- DI_Uploader
    - node_modules
    - public
        - bower_components
        - css
        - js
        index.html
    server.js
    package.json

1
为什么在网页中启动任何资源路径时都要以“./”开头?这会使浏览器将它们解释为相对于网页路径的路径,而这几乎永远不是您想要的。客户端路径通常应该以“/”开头。 - jfriend00
现在我看到托管版本使所有路径都以“http://website.com/DI_Uploader/”开头,那么我的先前评论可能会解释您的整个问题。这意味着浏览器中对“./css/styles.css”的请求将作为对服务器的“/DI_Uploader/css/styles.css”的请求到达,而这不是您设置的内容。 - jfriend00
@jfriend00 老实说,我一直都是这样做的,到目前为止也一直有效。我已经纠正了那个问题,但仍然存在这个问题,我会在问题中更新这个信息。 - Crash667
@jfriend00 我认为这也允许我从 DI_Uploader 中获取静态内容。文件夹结构是 DI_Uploader,然后里面是 public,然后里面是所有的 html、css、js。当我删除 ./ 后,我现在请求的是 website.com/css 而不是 website.com/DI_Uploader/css,我认为这也不正确。 - Crash667
但是,您直接将 express.static() 指向 public,因此磁盘层次结构中它上面的内容并不重要,对吗?当客户端请求 /js/app.js 时,该文件在硬盘驱动器上的确切位置是什么?它是 public/js/app.js 吗?其中 publicpath.join(__dirname, '/public') - jfriend00
显示剩余2条评论
1个回答

3
感谢 @jfriend00,我现在明白了为什么无法加载静态内容。原因是我将 static 设置在网站根目录上,而实际上需要设置在嵌套的 /DI_Uploader/ 文件夹中。要解决这个问题,可以使用虚拟路径来欺骗它。

请参见 http://expressjs.com/en/starter/static-files.html

更改后的代码如下:

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

你想让请求的URL中包含“/DI_Uploader/”吗?非常困惑。 - jfriend00
1
@jfriend00 我需要在URL中加入DI_Uploader,以便nginx能够识别并将其定向到正确的Node.js Express实例。此服务器还托管另外两个Web服务器,即另一个Express实例和Tomcat实例。我们正在尝试避免为正确的端口创建另一个DNS记录/VIP。我们这样做只是为了不必等待这里的网络团队。 简而言之:是的。 - Crash667
我能够在Express中重定向到正确的路由并提供HTML文件(app.use('./dev',...)),但是我的公共目录中的样式表仍然无法加载。 - AB1

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接