web-dev-qa-db-ja.com

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を取得しています。もう1つの奇妙なことは、それらのファイルのMIMEタイプがtext/HTMLに設定されていることです。

ここで何が悪いのですか?

同一のプロジェクト構造を持つプロジェクトがあり、構成は同じですが、問題なく機能し、この場合は機能しません。

7

静的ファイルを提供するためにNginxおよびExpressを構成する必要はありません。どちらも独立して仕事をすることができますが、あなたが選ぶのはあなた次第です。

これらの例では、質問で提供されているものと同じファイル構造を想定しています。

どちらの構成でも、HTMLの/からファイルをロードします。

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

静的ファイルサーバーとして表現、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

簡単な補足express.static()での__dirnameの使用は必要ありません。内部では(実際には here 65行目です)、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、APIサーバーとしてのExpress

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アプリ

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

お役に立てれば!

17
ContinuousLoad

nginx構成ファイルからtry_filesディレクティブを削除すると、問題が解決しました。

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

この2行がエラーを引き起こす理由だと思います。 2番目のものを削除して試してみることはできますか?おそらく、高速アプリがプライマリ静的配信フォルダー「node_modules」を設定しているため、アプリがメインスクリプトファイルを配信できないのはそのためです。

また、node_modulesディレクトリを静的フォルダーとして提供することは良い考えではないと思います。あなたの設定では、「bower」はjavascriptパッケージマネージャーとしてより適切な選択のように思えます。

ありがとう

1
supergentle

.の前に/を追加して、相対パスを示します。

<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>
0
Sua Morales

この構造がある場合:

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>

一方、本番環境では、フルパス+プロトコルを使用する方が安全です。

0
loretoparisi