为啥加载资产时nginx从平均服务器返回404?

Posted

技术标签:

【中文标题】为啥加载资产时nginx从平均服务器返回404?【英文标题】:Why does nginx return 404 from mean server when loading assets?为什么加载资产时nginx从平均服务器返回404? 【发布时间】:2015-12-11 03:13:45 【问题描述】:

我有一个 nginx 反向代理,它无法从上游平均堆栈服务器获取资产。这是一个非常小的单页应用程序。索引文件将加载得很好,但所有资产都以 404 未找到响应。当我有<base href="/"> 时,它在本地工作,但不能通过代理工作。我已阅读并实施了来自 proxying nginx Express - 404 on static files 和 NginX proxying Nodejs/Express - 404 on static files 的建议,并阅读了 this article 关于用 nginx 替换快速静态路由以帮助我解决此问题的建议,但都没有奏效。

请求的uri很简单

mydomain.com/myApp

文件夹结构如下:

myApp
├── app
└── public
    ├── css
    ├── js
    └── views

nginx 配置:

   1  server 
   2     listen 80;
   3 
   4     server_name mydomain.com;
   5
   6     location ~ ^/myApp/(libs/|img/|js/|css/) 
   7         root /path/to/myApp/public;
   8         access_log off;
   9         expires max;
  10     
  11
  12     location /myApp 
  13         proxy_pass http://mean-stack-ip:8080;
  14         proxy_http_version 1.1;
  15         proxy_set_header Upgrade $http_upgrade;
  16         proxy_set_header Connection 'upgrade';
  17         proxy_set_header Host $host;
  18         proxy_cache_bypass $http_upgrade;
  19     
  20 

server.js:

   1 // server.js
   2 
   3 // modules =================================================
   4 var express        = require('express');
   5 var app            = express();
   6 var bodyParser     = require('body-parser');
   7 var methodOverride = require('method-override');
   8 
   9 // set our port
  10 var port = process.env.PORT || 8080;
  11 
  12 // get all data/stuff of the body (POST) parameters
  13 // parse application/json 
  14 app.use(bodyParser.json());
  15 
  16 // parse application/vnd.api+json as json
  17 app.use(bodyParser.json( type: 'application/vnd.api+json' ));
  18 
  19 // parse application/x-www-form-urlencoded
  20 app.use(bodyParser.urlencoded( extended: true ));
  21 
  22 // override with the X-HTTP-Method-Override header in the request. simulate DELETE/PUT
  23 app.use(methodOverride('X-HTTP-Method-Override'));
  24 
  25 // set the static files location /public/img will be /img for users
  26 app.use(express.static(__dirname + '/public'));
  27 
  28 // routes
  29 require('./app/routes')(app); // configure our routes
  30 
  31 // startup our app at http://localhost:8080
  32 app.listen(port);
  33 
  34 // shoutout to the user                     
  35 console.log('Server listening on port ' + port + ' ...');
  36 
  37 // expose app
  38 exports = module.exports = app;

app/routes.js:

   1 // app/routes.js
   2 
   3 module.exports = function(app) 
   4 
   5     // route to handle all angular requests
   6     app.get('/myApp', function(req, res) 
   7         res.sendfile('./public/views/index.html');
   8     );
   9 
  10 ;

index.html:

   1 <!doctype html>
   2 <html lang="en">
   3 
   4 <head>
   5     <meta charset="UTF-8">
   6     <base href="/myApp/">
   7     <meta name="viewport" content="width=device-width, initial-scale=1">
   8 
   9     <title>My App</title>
  10     
  11     <!-- CSS -->
  12     <link rel="stylesheet" href="libs/bootstrap/dist/css/bootstrap.min.css">
  13     <link rel="stylesheet" href="libs/font-awesome/css/font-awesome.min.css">
  14     <link rel="stylesheet" href="css/style.css">
  15 
  16     <!-- JS -->
  17     <script src="libs/jquery/dist/jquery.min.js"></script>
  18     <script src="libs/bootstrap/dist/js/bootstrap.min.js"></script>
  19     <script src="libs/angular/angular.min.js"></script>
  20     <script src="libs/angular-route/angular-route.min.js"></script>
  21 
  22     <!-- ANGULAR -->
  23     <script src="js/controllers/mainController.js"></script>
  24     <script src="js/appRoutes.js"></script>
  25     <script src="js/app.js"></script>
  26 </head>
  27 
  28 <body ng-app="myApp" ng-controller="mainController as main">
  29     <div id="body-container" class="container-fluid">
  30         
  31         <!-- Angular dynamic content -->
  32         <div ng-view></div>
  33 
  34     </div>
  35 </body>
  36 
  37 </html>

我是新来的,意味着堆栈和全新的 nginx,所以任何帮助将不胜感激。我基本上无法进一步构建任何东西,因为我无法提供我的应用程序!

提前致谢,

Amr

【问题讨论】:

我遇到了类似的问题,我想在 nginx conf 文件中使用 /myapp 访问 NodeJS 应用程序。我可以让它为静态 index.html 提供服务,而不是因为重定向不正确而找不到其他 JS 文件。 【参考方案1】:

您可以尝试代理所有请求,而不仅仅是 /myApp。

【讨论】:

@AmrGaber 你能否详细说明你是如何修复它的 如果您在 nginx 网关后面运行多个服务,这将不起作用。您可能有需要重定向到特定端口号的 /app1/app2 @mortond 那么多个应用的​​解决方案是什么? @IsaacPak 我对这个问题的解决方案是创建 2 个 .conf 文件目录,其中一个目录用于为 todo.example.comskynet.example.com 等应用程序定义了 server 域级别配置的应用程序。另一个 .conf 目录用于 locations,例如 /api1//api2。这些配置文件包含在我的主 nginx.conf 文件中的不同位置 include /etc/nginx/conf.d/apis/*.conf;include /etc/nginx/conf.d/applications/*.conf; 对于server 级别的配置,location/,对于 API 级别,locations 是 /api//endpoint/ 不错。我的设置与操作相同。但我的解决方案是将应用程序根目录添加到 express 静态函数中。所以在操作的情况下,我会做类似的事情: app.use('/myApp', express.static(__dirname + '/public'));【参考方案2】:

当我使用docker container links 连接我的容器时,我的日志中出现了同样的错误,就像在一些旧文档中一样。 Docker container networking 是要使用的东西。我有另一篇 more details here 的帖子,我的网站 www.starbug.com 使用它,并链接到我的 git repo 的完整源代码。

我不想在另一篇文章中重复我的答案,但基本的想法是创建一个 docker 网络并在配置文件中通过它们的名称来引用容器。这对我有用:

docker network create nginx-proxy

docker run --net nginx-proxy --name nginx-ss-00.starbug.com -v /var/run/docker.sock:/tmp/docker.sock -d -p 80:80 -p 443:443 nginx-ss.starbug.com

docker run --net nginx-proxy --name aai-gunicorn-00 -d -p 8080:8080 aai-gunicorn

在我的 nginx 配置文件中

server 

    server_name  www.starbug.com;
    listen       80;

    # reverse proxy
    location / 

        # TODO Assumes flask container is named aai-gunicorn-00 and running on port 8080
        proxy_pass http://aai-gunicorn-00:8080;

        # Redefine the header fields that NGINX sends to the upstream server
        proxy_set_header Host $host;
        proxy_set_header X-Forwarded-Proto $scheme;
        proxy_set_header X-Real-IP $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

        client_max_body_size 5M;

    


【讨论】:

以上是关于为啥加载资产时nginx从平均服务器返回404?的主要内容,如果未能解决你的问题,请参考以下文章

azure 应用服务上的 Angular 应用 - 从资产文件夹加载配置文件时出现 404 错误

为啥我无法加载位于资产目录中的图像?

为啥 nginx 位置返回 404 错误?

Nginx 意外返回 Nodejs API 的 404

使用 Nginx 刷新页面显示 404 错误 [重复]

为啥 System.Net.Browser.ClientHttpWebRequest 访问无效服务器地址时返回 404?