[英]Express + Nginx. Can't serve static files
This is my project folder 这是我的项目文件夹
/
public/
index.html
main.js
adaptor.js
main.css
node_modules/
socket.io/
index.js
and this is static file configuration in my 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'));
})
and this is my 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>
and this is my nginx configuration 这是我的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;
}
But I am getting 404 on all the scripts. 但是我在所有脚本上都获得了404。 And an another strange thing is that mime-type on those files is set to
text/HTML
另一个奇怪的事情是这些文件上的mime-type设置为
text/HTML
What am I doing wrong here? 我在这做错了什么?
I have a project, with an identical project structure, and it has the same configuration, but it works for it, and it isn't working in this case. 我有一个项目,具有相同的项目结构,并且具有相同的配置,但它适用于它,并且在这种情况下它不起作用。
You don't need to configure Nginx and Express to serve static files. 您无需配置Nginx 和 Express来提供静态文件。 Both are capable of doing the job independently, but it is up to you to choose.
两者都能够独立完成工作,但您可以自行选择。
For these examples I am assuming the same file structure provided in your question. 对于这些示例,我假设您的问题中提供了相同的文件结构。
In both configurations, load files from / in HTML: 在这两种配置中,从/中加载HTML文件:
<script src="/main.js"></script> <!-- loads from myapp/public/main.js -->
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
Quick side note : the use of __dirname
in express.static()
is not required. 快速注意 :
__dirname
在express.static()
使用__dirname
。 Under the hood (actually, it's here on line 65) , Express uses the native Node.js path.resolve() . 引擎盖下(实际上,这是在这里第65行),快速使用本机的Node.js path.resolve() 。 From the docs:
来自文档:
The path.resolve() method resolves a sequence of paths or path segments into an absolute path.
path.resolve()方法将一系列路径或路径段解析为绝对路径。
Using path.resolve(__dirname, 'public')
actually returns the same as path.resolve('public')
. 使用
path.resolve(__dirname, 'public')
实际上返回与 path.resolve('public')
。 I am thinking that your problem was really telling Nginx to serve static files AND proxy the same requests to Express. 我认为你的问题确实告诉Nginx提供静态文件并代理相同的Express请求。 OK, on to the rest of my answer.
好的,继续我的答案。
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;
}
}
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;
}
}
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);
Hope this helps! 希望这可以帮助!
从nginx配置文件中删除try_files
指令解决了我的问题。
app.use(express.static(path.join(__dirname, '/public')));
app.use(express.static(path.join(__dirname, '/node_modules')));
I think those two lines are the reasons why it raises an error. 我认为这两行是导致错误的原因。 Can you delete the second one and give it a try?
你能删除第二个并尝试一下吗? Maybe your express app sets the primary static serving folder "node_modules" and that is why the app cannot serve your main script files.
也许你的快递应用程序设置主要静态服务文件夹“node_modules”,这就是应用程序无法提供主脚本文件的原因。
Also, I don't think it is good idea to serve node_modules directory as static folder. 另外,我不认为将node_modules目录作为静态文件夹提供是个好主意。 I think in your setup, "bower" seems more appropriate choice as a javascript package manager.
我认为在您的设置中,“bower”似乎更适合作为javascript包管理器。
Thanks 谢谢
Add a .
添加一个
.
before the /
to denote a relative path: 在
/
之前表示相对路径:
<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>
If you have this structure: 如果你有这个结构:
myApp
app.js
-public/
-js/
In app.js
you should do like this: 在
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')));
});
where staticRoutes
is an array like 其中
staticRoutes
是一个数组
staticRoutes=[
'services/'
'about/'
];
and in the html (development) 并在HTML(开发)
<script type="text/javascript" src="js/util.js"></script>
<a href="/about">About Us</a>
while when in production is safer using the full path + protocol. 而在生产中使用完整路径+协议更安全。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.