2012-12-26 116 views
13

我有几个应用程序运行在Nginx反向代理的后面,其中一个是使用Express.js的节点服务器。我使用这个Nginx的配置进行代理domain.com/demo/app/<path>localhost:7003/<path>Nginx反向代理重写Node.js

http { 

    ... 

    server { 

     listen 80; 
     server_name domain.com; 

     ... 

     location /demo/app { 

      proxy_set_header Host $host; 
      proxy_set_header X-Real-IP $remote_addr; 
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 
      proxy_set_header X-Scheme $scheme; 

      rewrite ^/demo/app/?(.*) /$1 break; 
      proxy_pass http://localhost:7003; 
     } 

     ... 
    } 
} 

这个伟大的工程和app就好像是在/扎根接收请求。问题是app处理它自己的静态文件,并可能请求路由,如css/app.cssimages/image.jpg。但是由于反向代理,这些实际上分别存在于/demo/app/css/app.css/demo/app/images/image.jpg

我已经解决了这个问题,让Nginx向Node传递一个自定义标题,指明根节点,Node节点服务器向所有后续请求的URL预先指定。但是现在我的代码充斥着这些根路径字符串。例如,我的部分后端模板:

link(rel='stylesheet', href="#{basePath}/css/base.css") 
link(rel='stylesheet', href="#{basePath}/css/skeleton.css") 
link(rel='stylesheet', href="#{basePath}/css/layout.css") 

什么是更优雅的方式来处理这个问题?没有办法让Nginx识别来自上游服务器的请求,并自动将它们转发给该服务器?

回答

9

我已经nginx的静态文件,甚至没有通过(其中包括在nginx.conf)这些请求中加入位置指令到应用程序的nginx的配置文件到节点:

location ~ /(img|js)/ { 
    rewrite ^(.*)$ /public/$1 break; 
} 

location/{ 
    proxy_pass http://localhost:3000/; 
    ... 
} 

如果请求到达/ img或/ js目录nginx分别从/ public/img或/ public/js目录提供文件。所有其他请求都被代理到节点。如果你需要的话,你可以添加更多的目录(比如/ css或/ views,如果你想在节点和浏览器中使用模板,并且在这些目录中有任何目录结构),nginx只是在/公开给他们,并从那里获取文件,甚至不知道你的节点应用程序。

+0

你如何处理AJAX请求?我不想在JavaScript中用'/ demo/app'预先加入AJAX URL –

+0

通过上面的配置,所有请求(除/ img/...和/ js/...之外)都会被代理node.js假设它监听端口3000.'''location /''匹配所有未被前一个location指令匹配的请求。 – esp

+0

如果你需要让你的应用程序处理请求,就好像他们来到'/'你仍然可以按照你的方式重写请求...我宁愿在应用程序内部有这种路由,但这是我个人的偏好...我我不确定自己能够正确理解你想实现的目标,但是在链接中不包含{basepath}的唯一方法是按照我的方式重写请求。它也允许不在节点中处理静态文件,但如果你愿意,你仍然可以代理它们... – esp