Express + Nginx。无法提供静态文件

时间:2017-10-11 15:37:01

标签: node.js express nginx

这是我的项目文件夹

/
  public/
    index.html
    main.js
    adaptor.js
    main.css
  node_modules/
    socket.io/
  index.js

这是我的index.js中的静态文件配置

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

这是我的index.html

  <script src="/socket.io/socket.io.js" charset="utf-8"></script>
  <script src="/adapter.js" charset="utf-8"></script>
  <script src="/main.js" charset="utf-8"></script>

这是我的nginx配置

    location / {
            # First attempt to serve request as file, then
            # as directory, then fall back to displaying a 404.
            try_files $uri $uri/ /index.html =404;
            proxy_pass http://localhost:8080;
    }

但是我在所有脚本上都获得了404。另一个奇怪的事情是这些文件的mime-type设置为text/HTML

我在这里做错了什么?

我有一个项目,具有相同的项目结构,并且具有相同的配置,但它适用于它,并且在这种情况下它不起作用。

5 个答案:

答案 0 :(得分:13)

您不需要配置Nginx Express来提供静态文件。两者都能够独立完成工作,但您可以自行选择。

对于这些示例,我假设您的问题中提供了相同的文件结构。

在这两种配置中,从/中加载文件:

<script src="/main.js"></script> <!-- loads from myapp/public/main.js -->

Express为静态文件服务器,Nginx为反向代理

表达应用

const express = require('express');
const app = express();

app.use(express.static('public')); // notice the absence of `__dirname`, explained later on

// if the request URL doesn't match anything in the 'public' folder,
// it will start searching here next.
app.use(express.static('some_other_folder'));

// from my testing, express will automatically locate index.html if
// it is in a static folder. Declaring a route is not required.

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

app.listen(8080);

// GET / => index.html
// GET /main.js => main.js

快速注释:不需要在__dirname中使用express.static()。在引擎盖下(实际上,它是第65行的here),Express使用本机Node.js path.resolve()。来自文档:

  

path.resolve()方法将一系列路径或路径段解析为绝对路径。

使用path.resolve(__dirname, 'public')实际上会返回与path.resolve('public')相同的。我认为你的问题确实告诉Nginx提供静态文件并代理相同的Express请求。好的,接下来是我的答案。

Nginx配置

server {
  listen 8081; # must be different port from Express
  server_name example.com;
  location / {
    # hand ALL requests back to express
    proxy_pass http://localhost:8080; 
  }
}

Nginx作为静态文件服务器,Express作为API服务器

Nginx配置

server {
  listen 8081;
  server_name example.com;
  location / {
    root /path/to/website/public;
    index index.html;
    try_files $uri $uri/ @express; # instead of 404, proxy back to express using a named location block;
    # source: https://stackoverflow.com/a/15467555/8436941
  }
  location @express {
    proxy_pass http://localhost:8080;
  }
}

Express app

const express = require('express');
const app = express();

// actually, Nginx has already taken care of static files. You can still define other routes for API functions for example.
app.get('/my/api', (req, res) => {/* query database, etc. */});

app.listen(8080);

希望这有帮助!

答案 1 :(得分:4)

nginx配置文件中删除arr = [{a: 1, b: 2, c:3}, {a:2, b:10, c:2}, {a:9, b:2, c:8}]指令为我解决了这个问题。

答案 2 :(得分:1)

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

我认为这两行是导致错误的原因。 你能删除第二个并尝试一下吗?也许你的快递应用程序设置主要静态服务文件夹“node_modules”,这就是应用程序无法提供主脚本文件的原因。

另外,我不认为将node_modules目录作为静态文件夹提供是个好主意。我认为在您的设置中,“bower”似乎更适合作为javascript包管理器。

由于

答案 3 :(得分:0)

.之前添加/以表示相对路径:

<script src="./socket.io/socket.io.js" charset="utf-8"></script>
<script src="./adapter.js" charset="utf-8"></script>
<script src="./main.js" charset="utf-8"></script>

答案 4 :(得分:0)

如果你有这个结构:

myApp
  app.js
  -public/
     -js/

app.js中你应该这样做:

self.app.use(express.static(path.join(__dirname, 'public')));
staticRoutes.forEach(route=> {
            self.app.use(BASEPATH+route,express.static(path.join(__dirname, 'public')));
        });

其中staticRoutes是一个类似

的数组
staticRoutes=[
'services/'
'about/'
];

和html(开发)

<script type="text/javascript" src="js/util.js"></script>
<a href="/about">About Us</a>

虽然使用完整路径+协议在生产中更安全。