使用Nginx代理本地Rails后端进程 - 本地开发环境搭建

配置

rails 启动脚本

bundle exec rails s -p 3011 -b 0.0.0.0

nginx 配置文件

# nginx.conf
server {
  location / {
       root   /data/project-name/public;
       index  /products;
       proxy_set_header Host $http_host;
       proxy_pass http://localhost:3011;
   }
   # static file path
   location /data/project-name/public/ {
       rewrite  ^/data/project-name/public(.*)$ $1 last;
   }
   # static file
   location /uploads {
       root /data/project-name/public;
   }
}

期间遇到的问题

业务逻辑:还是说我做的电商网站,如果客户没有添加过地址,新客户,先购买了商品,添加到购物车,然后点击进入结算中心,这时候会redirect到新建地址页面,如果NGINX没有给后端传递host变量,则会引起turbolinks 异常。

Uncaught DOMException: Failed to execute 'replaceState' on 'History': A history state object with URL 'http://localhost:3011/addresses/new' cannot be created in a document with origin 'http://localhost:8080' and URL 'http://localhost:8080/orders/new'.
    at r.update (http://localhost:8080/assets/turbolinks.self-1d1fddf91adc38ac2045c51f0a3e05ca97d07d24d15a4dcbf705009106489e69.js?body=1:6:11571)
    at r.replace (http://localhost:8080/assets/turbolinks.self-1d1fddf91adc38ac2045c51f0a3e05ca97d07d24d15a4dcbf705009106489e69.js?body=1:6:10898)
    at r.replaceHistoryWithLocationAndRestorationIdentifier (http://localhost:8080/assets/turbolinks.self-1d1fddf91adc38ac2045c51f0a3e05ca97d07d24d15a4dcbf705009106489e69.js?body=1:6:29674)
    at r.followRedirect (http://localhost:8080/assets/turbolinks.self-1d1fddf91adc38ac2045c51f0a3e05ca97d07d24d15a4dcbf705009106489e69.js?body=1:6:25092)
    at r.visitCompleted (http://localhost:8080/assets/turbolinks.self-1d1fddf91adc38ac2045c51f0a3e05ca97d07d24d15a4dcbf705009106489e69.js?body=1:6:9736)
    at r.complete (http://localhost:8080/assets/turbolinks.self-1d1fddf91adc38ac2045c51f0a3e05ca97d07d24d15a4dcbf705009106489e69.js?body=1:6:23145)
    at r.<anonymous> (http://localhost:8080/assets/turbolinks.self-1d1fddf91adc38ac2045c51f0a3e05ca97d07d24d15a4dcbf705009106489e69.js?body=1:6:24918)
    at http://localhost:8080/assets/turbolinks.self-1d1fddf91adc38ac2045c51f0a3e05ca97d07d24d15a4dcbf705009106489e69.js?body=1:6:27435

在请求http://localhost:8080/addresses/new的时候,返回一个错误的headerTurbolinks-Location:http://localhost:3011/addresses/new

turbolinks官方文档说明: https://github.com/turbolinks/turbolinks/blob/0380f01b61e0a9e9a7516674c3e76c15efccd90e/README.md#following-redirects

When you visit location /one and the server redirects you to location /two, you expect the browser’s address bar to display the redirected URL.

However, Turbolinks makes requests using XMLHttpRequest, which transparently >follows redirects. There’s no way for Turbolinks to tell whether a request resulted in a redirect without additional cooperation from the server.

To work around this problem, send the Turbolinks-Location header in response to a visit that was redirected, and Turbolinks will replace the browser’s topmost history entry with the value you provide.

The Turbolinks Rails engine sets Turbolinks-Location automatically when using redirect_to in response to a Turbolinks visit.

官方文档说的意思是,如果存在重新向的情况,turbolinks并不会将地址栏url自动设置为重定向后的url,而是根据一个response的header来判断,Turbolinks-Location,这个header是由rails释放出来的。

如果NGINX在向后端realserver请求时,没有带Host这个header,后端的realserver(rails server)则直接将Turbolinks-Location设置为它自己启动时的IP和端口,在本例中就是Turbolinks-Location:http://localhost:3011/addresses/new

要解决此问题,只需要在nginx 配置中增加 proxy_set_header Host $http_host;,此设置含义是,在请求时,nginx将真正的前端主机名$http_host,通过Host传递给后端的realserver。