先说说奇葩的需要:https 转其余网站的 http
在我的项目里用 iframe 内嵌其余网站,这个“其余网站”不是咱们开发的,并且是 http,
但浏览器会默认阻止从 https 网站向 http 地址发动申请
因而初步的解决方案是:用咱们本人的服务器 nginx 转发一次,尽管服务器到“其余网站”的传输还是明文,但至多能够做到甩锅(至多用户到咱们的服务器的传输是 SSL……)
而后这个“其余网站”就呈现了有限重定向问题。
另外,依据以往的经验,在给 WordPress 加 https 的时候,也可能会遇到有限重定向的问题。
起因
实质上是因为:“其余网站”的服务程序具备 申请头校验。
通常来说,nginx 转发的申请,是带有 原始申请头 信息的申请。
比方:
nginx 服务器的地址是 https://server1.domin:1111
生产服务器的地址是 http://server2.domin:2222
浏览器向 https://server1.domin:1111 发动申请
此时,尽管 nginx 把申请代理到了 http://server2.domin:2222
但因为一系列的参数设置,http 申请头中的信息还是 https://server1.domin:1111
这种状况下,如果“其余网站”的服务程序(Apache 或 nginx)中退出了申请头校验,
也就是说,如果端口不是 2222,就重定向;
如果地址不是 server2.domin,就重定向。
而咱们的 nginx 曾经把申请头改成了原始信息,天然不能通过他们的验证,所以就会被强制重定向了。
如图,它把我的 38004 端口的申请重定向到了默认的 443, 阐明对方服务器有地址校验,而且重定向只扭转了端口。
而如果我的 nginx 恰好也用的 443, 就会有限重定向了。
解决
咱们先来看看通常应用的 nginx 的重写参数:
server {
listen 38002 ssl;
server_name server1.domin;
ssl_certificate server1.domin.cer;
ssl_certificate_key server1.domin.key;
location / {
proxy_set_header Host $host;
proxy_set_header X-Real_IP $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr:$remote_port;
proxy_pass http://server2.domin:2222/;
}
}
这种状况下,就是间接在代理的申请中,退出原始申请头信息
那么咱们怎么改呢?
咱们要让对方服务器认为,nginx 发过来的申请不是代理过来的,而是间接发过来的。
再换种形式说,此时 nginx 的作用不再是反向代理,而是正向代理,目标是暗藏真正的申请信息,让对方服务器认为就是 nginx 间接申请的对方服务器。
所以咱们要把 ip、端口等等参数间接写死。
server {
listen 443 ssl;
server_name server1.domin;
ssl_certificate server1.domin.cer;
ssl_certificate_key server1.domin.key;
location / {
proxy_set_header Host server2.domin; // 对方服务器的域名
proxy_set_header X-Real-IP 123.123.123.123; // 对方服务器的实在地址,从控制台中找到
proxy_set_header X-Forwarded-For $123.123.123.123:80;
proxy_set_header X-Forwarded-Host server2.domin; // 对方服务器的域名
proxy_set_header X-Forwarded-Port 80; // 对方服务器的端口
proxy_pass http://server2.domin:2222/;
}
}
于是代理过程就变成了这样:
总结
在咱们不得不用 nginx 代理,并且无奈让对方配合的状况下
只有把 http 中的申请头信息替换为对方网站的申请头信息(而不是应用原始信息)
就能够通过对方服务器的 host 验证了。
工夫仓促,有些中央可能说的不准,但目前能用,如有谬误欢送斧正。
本文只公布 segmentfault,禁止转载,如在其余平台看到请举报。