在 https 页面嵌入 http 页面的解决办法

最近在做一个关于在线视频教育的项目,其中用到了第三方的一个视频直播服务,需要在我们的界面中使用 iframe 引入第三方服务提供的页面来启动直播客户端。

因为我们现在生产环境中的 Web 页面全部使用了 https 的协议,而第三方的服务商因为只提供 http 的页面,而不支持 https,所以在打开界面是会提示 This request has been blocked; the content must be served over HTTPS.,所以我们采用了 nginx 代理的方式来解决此问题。下面是技术方案:

为了配置简单,我们自己使用的 子目录 与第三方相同,同样都是 /webcast/

  • 需嵌入的第三方服务页面 URL: http://zhibo.thirddomain.com/webcast/site/entry/live-xxxxxxxxx
  • 我们自己的域名: zhibo.mydomain.com

首先我们做了简单的 nginx 反向代理

...
  location /webcast/ {
    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_pass http://zhibo.mydomain.com;
  }
...

配置完成,重新加载 nginx 配置。

打开页面后发现嵌入的页面出现了 404 错误,怀疑是对方做了限制,经过排查发现是对于 header 中的 Host 做了限制。于是改成如下的配置:

...
  location /webcast/ {
    proxy_set_header Host "zhibo.thirddomain.com";
    proxy_set_header X-Real-Ip $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass http://zhibo.mydomain.com;
  }
...

再次重新加载 nginx 配置,页面可以正常打开了,但是打开的页面在经过验证传递的参数后,进行了 302 跳转,而跳转后的页面同样不是 https。只能再次修改配置,拦截并替换跳转后的界面。于是代码改为如下:

...
  location /webcast/ {
    proxy_set_header Host "zhibo.thirddomain.com";
    proxy_set_header X-Real-Ip $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_pass http://zhibo.mydomain.com;

    proxy_redirect ~http://zhibo.thirddomain.com/webcast/site/event/(.+)$ https://zhibo.mydomain.com/webcast/site/event/$1;
  }
...

重新加载 nginx 配置后,问题解决。

此方式虽然解决了 https 页面嵌入 http 页面的问题。但是会引入新的问题,理想状态是我们的反向代理只做建立连接和启动本地应用。但是如果第三方服务流量全是经由代理转发的话会对自己服务器造成很大的压力。所以此方案在流量不是很大的情况下可行。

张迪

继续阅读此作者的更多文章

北京