ngxin和nodejs转发遇到的问题
发布于 2个月前 作者 jinwyp 325 次浏览 来自 问答

目前网站的教程都是nginx 直接80 端口转发给nodejs 3000 ,而且都是/ 根转发.

我现在有这样一样情况 nodejs 3000端口上 程序有路由/api 下面是接口 /website下面是网站,
nodejs目录文件的public 文件夹是静态文件,里面有图片和js文件, 正常nodejs应用测试环境下 /website/ 路由可以正常render index.ejs 文件 可以正常访问,读取的js,图片都正常

如果用nginx 我设置一个域名 www.a.com 转发给nodejs 不是/ 根路径 而是 /website下面 , 就是说www.a.com 直接访问的是nodejs程序的/website路由, 但静态文件全部路径都错了, 无法访问到js和图片, 因为这时静态文件还是访问的是/根路由下面的, 怎么处理? 是不是只能在nginx开通public静态文件处理,而无法让nodejs直接提供静态文件服务了?

我用api.a.com 转发给 nodejs 的/api 路由 就可以正常访问,因为只有json数据没有 html 和静态文件

6 回复
  1. 标题里 nginx 拼错了…
  2. 我们的做法是:在 config 里定义一个 rootPath 这样的变量,然后处理静态文件的时候在前面加上这个变量

说得好复杂,看不懂你的意思。 一般性来讲,public 放静态文件,nginx 根目录指向这个文件夹 然后配置 tryfiles 把不存在的请求转发到 node.js 3000端口就可以了。这样调试和布署的路径都会是统一的。

root /path/to/express/public;
tryfiles $uri $uri/index.html @express;

location @express {
    proxy_set_header Upgrade $http_upgrade;
    proxy_set_header Connection "upgrade";
    proxy_http_version 1.1;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $host;
    proxy_pass http://localhost:3000;
}

贴一下 问题的nginx 配置

add_header X-Frame-Options SAMEORIGIN; add_header X-Content-Type-Options nosniff; #add_header X-XSS-Protection "1; mode=block"; #add_header Content-Security-Policy "default-src 'self’; script-src ‘self’ ‘unsafe-inline’

upstream admin_node { server 127.0.0.1:3000;

keepalive 16; }

upstream admin_test_node { server 127.0.0.2:3003; }

server { listen 80; server_name website.aaa.com ; keepalive_timeout 70; #ssl_session_cache shared:SSL:50m; #ssl_session_timeout 5m; #ssl_prefer_server_ciphers on; #ssl_protocols TLSv1 TLSv1.1 TLSv1.2; #ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH RSA+AESGCM RSA+AES !RC4 !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS"; #ssl_certificate /etc/nginx/ssl/api.crt; #ssl_certificate_key /etc/nginx/ssl/api.key; #ssl_dhparam /etc/nginx/ssl/xn–btrz41b.com.pem; #resolver 223.5.5.5 223.6.6.6; #ssl_stapling on; #ssl_trusted_certificate /etc/nginx/ssl/api.crt; #add_header Strict-Transport-Security "max-age=31536000; includeSubdomains;"; location / { proxy_hide_header X-Powered-By; proxy_hide_header X-Page-Speed; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Client-IP $remote_addr; proxy_set_header Host $host; proxy_set_header REMOTE-HOST $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://admin_node/website; } location /test { proxy_hide_header X-Powered-By; proxy_hide_header X-Page-Speed; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Client-IP $remote_addr; proxy_set_header Host $host; proxy_set_header REMOTE-HOST $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_pass http://admin_test_node/website; } }

现在按这个配置 访问website.aaa.com 那么进入到 nodejs 里面的路由/website 渲染的index.html 文件 带的js和图片 全部都地址错误 无法访问

@klesh 就是说 必须要在nginx里面配置单独针对静态文件的转发, 而不能直接让nodejs提供静态文件的服务?

例如直接转发/ 根路径 就可以让nodejs处理静态文件, 但只要是转发到nodejs二级路径就不行了对吗?

@jinwyp 不是行不行的问题,是有没有必要的问题。为什么要用 nginx ?就是因为它处理静态文件效率更高,效果更好!全部转发了还要nginx来做什么呢?

映射到二级路径行不行我还没这么干过,但应该是可以的。问题是你把二级的挂载成一级的整个路径引用就乱套了。静态页面原本指向 /website/abc.html 已经不存在,对服务器来讲现在只有 /abc.html

一般性来讲,你构造一个 express 工程,它已经帮你把目录结构处理好了,把所有的静态资源放在 public 里面,包括 css/js/img,和其它的库如 bootstrap/jquery 视图 就放在 views 里面。 开发时,引用静态资源直接以相对根路径的形式引用: /lib/bootstrap/css/bootstrap.min.css /lib/jquery/jquery.min.js 这样 express 默认会去 public 文件找这些文件。 布署时,整个文件夹拷到服务器,nginx 的 root 指到 public,然后用tryfiles把非静态文件请求转发到 express app 的端口就行了。

以上就能统一开发时和生产时的路径引用。很简单的,别想太复杂了。

“proxy_pass” cannot have URI part in location given by regular expression, or inside named location, or inside “if” statement, or inside “limi t_except” block in /etc/nginx/sites-enabled/

我想访问 admin.xxx.com 跳转到nodejs/admin的路由上

回到顶部