Web 技术研究所

我一直坚信着,Web 将会成为未来应用程序的主流

nginx 配置之 proxy_pass 神器!

  proxy 模块是 nginx 中最碉堡的模块之一。就是有了 proxy 模块,nginx 才能和其它 http 服务器关联起来,极大程度地提高了 nginx 的可用性。proxy 这个模块比较大,光是指令就有一大堆。这里我们只是简单地介绍一下它最核心的指令 —— proxy_pass 。
  当我们遇到跨域问题,而且客户端无法支持 CORS 时,最好的办法就是让服务器来做代理。在前端页面所在的服务器 nginx 配置上开一个路由,然后使用 proxy 去请求另一个域名下的资源。如果跨域资源也部署在同一台机器上,我们甚至可以 proxy 到 127.0.0.1,比如:
location /api { proxy_pass http://127.0.0.1:1234; }   当客户端请求 /api 这个路径下的资源时服务器就会帮助我们去 127.0.0.1 的 1234 端口上取资源,解决了跨域的问题。proxy_pass 会将当前的 $uri 带过去,所以如果 /api 这个路由是我们擅自加的,在发送到目标服务前可以使用 rewrite 来处理掉这个多余的路由,比如:
location /api/ { rewrite ^/api/(.*) /$1 break; proxy_pass http://127.0.0.1:1234; }   rewrite 的作用是修改 $uri,但要注意 rewrite 要有个重新匹配 location 的副作用。由于 proxy_pass 的处理阶段比 location 处理更晚,所以这里需要 break 掉,以防止 rewrite 进入下一次 location 匹配而丢失 proxy_pass。
  另外还有一个值得注意的地方,proxy_pass 后面的 host 如果填写一个域名的话,这个域名将会在 nginx 启动时解析。如果 nginx 启动时域名无法解析将会抛出异常无法启动,比如: location /api { proxy_pass http://xxx; } nginx: [emerg] host not found in upstream "xxx"   而且由于 nginx 解析域名是在启动时做的,所以在 nginx 启动之后修改域名的解析对 nginx 是不会生效的。
  如果觉得让 nginx 启动时去查询 DNS 这件事不靠谱(我就不推荐这么做,因为 DNS 确实是不可控的),那么可以在 proxy_pass 时到某个 IP 上,hostname 可以通过 porxy_set_header 指令强制设置 proxy 的 HTTP 请求中的 Host 字段来修改它,比如:
location /api { proxy_set_header Host api.web-tinker.com; proxy_pass http://127.0.0.1:8080; }   除了设置 Host 这个请求头之外,proxy_set_header 还能设置别的头,只要你的脑洞够大就可以用它来做更多奇怪的事情!
  另外还有个要注意的点。proxy_pass 默认使用的是 http 1.0,可以通过 proxy_http_version 指令让它使用 http 1.1,以便开启 keepalive 之类的功能。
location /api { proxy_http_version 1.1; proxy_pass http://127.0.0.1:8080; }
网名:
54.234.0.*
电子邮箱:
仅用于接收通知
提交 悄悄的告诉你,Ctrl+Enter 可以提交哦
神奇海螺
[查看全部主题]
各类Web技术问题讨论区
发起新主题
本模块采用即时聊天邮件通知的模式
让钛合金F5成为历史吧!
次碳酸钴的技术博客,文章原创,转载请保留原文链接 ^_^