前言

 这几天有个需求:做个表单页面,要求后台人员能自定义发布表单,用户来填写表单。我一想,这不麦克表单有现成的吗,拿来就用!发布表单后,可以选择使用iframe方式嵌入网站,一切顺利。

 当时的网站是http协议,后来升级了https,发现完全加载不出来。原因是浏览器的安全限制,在https协议下不允许有http的iframe请求。然而,除了交钱,也不能将麦克的协议变成https

 前端无法解决这个问题,想了想,可以使用Nginx反向代理来实现。说白了,就是把自己的服务器当做代理服务器,骗过浏览器,让它以为是向自己的服务器发请求。

正文

 目标网址:http://www-smcic-cn.mikecrm.com/i0RPpTH

 代理网址:https://www.smcic.cn/mikecrm/

 首先,将前端的iframe src属性地址改成自己的

<iframe src="https:www.smcic.cn/mikecrm/"></iframe>

 接下来是Nginx配置,需要将以下代码写在https的server中:

location /mikecrm/ {
proxy_pass http://www-smcic-cn.mikecrm.com/i0RPpTH;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
}

 试了试,确实能加载iframe。但是,iframe中有大量的css、js、img等资源要请求,并没有通过以上配置代理,结果全部返回404,很是苦恼。

 通过分析资源请求路径,发现是这样的,例如 http://www-smcic-cn.mikecrm.com/css/... 或 http://www-smcic-cn.mikecrm.com/form/.../......

 逻辑并不难,奈何本人正则水平太差,在经历了痛苦的尝试之后,终于摸索出了一条道路:

resolver 223.5.5.5 119.29.29.29 114.114.114.114;  # 域名解析,要写在server外面

location /mikecrm/ {
set $flag 0;
if ( $request_uri = "/mikecrm/" )
{
set $para "i0RPpTH";
}
if ( $request_uri != "/mikecrm/" )
{
set $flag "${flag}1";
}
if ( $request_uri ~ /mikecrm/(.*) )
{
set $paaa $1;
set $flag "${flag}2";
}
if ( $flag = "012" )
{
set $para $paaa;
}
proxy_pass http://www-smcic-cn.mikecrm.com/$para;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
}

 注意及解释:

   1.在代理地址proxy_pass中如果存在变量($para),必须要使用resolver指令解析变量中的域名,因为Nginx一开始就会解析好域名。(其实是变量涉及到域名才需要用resolver,我这里没涉及到域名,想不通为什么也必须要resolver)。推荐使用多个dns解析地址,最好是国内的。

   2.Nginx中不支持if else,也不支持条件嵌套,如果有条件判断与的需求,可以参照后三个if{}的配合使用

   3.proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; 可记录真实的用户访问IP

   4.大概思路是,先判断请求uri,如果是第一次请求(即/mikecrm/,请求iframe页面)则转向访问http://www-smcic-cn.mikecrm.com/i0RPpTH,如果不是第一次请求(即/mikecrm/.../.....,请求资源)则转向访问资源。

优化

 虽然取得阶段性成功,但此配置只能适用于特定的这个表单,要多个表单都能够使用,还需要再改配置

 前端请求地址:

https://www.smcic.cn/mikecrm/i0RPpTH/

 Nginx配置:

location /mikecrm/ {
set $flag 0;
if ( $request_uri ~ ^/mikecrm/(\w*)/$ )
{
set $mikeid $1;
}
if ( $request_uri = /mikecrm/$mikeid/ )
{
set $para $mikeid;
}
if ( $request_uri != /mikecrm/$mikeid/ )
{
set $flag "${flag}1";
}
if ( $request_uri ~ ^/mikecrm/(\w*)/(.*) )
{
set $paaa $2;
set $flag "${flag}2";
} if ( $flag = "012" )
{
set $para $paaa;
}
proxy_pass http://www-smcic-cn.mikecrm.com/$para;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Real-IP $remote_addr;
}

 参考文档:

  1.https://www.cnblogs.com/taosim/articles/4097728.html

  2.https://blog.csdn.net/u014296316/article/details/80973530

  3.https://www.cnblogs.com/netsa/p/6383094.html

  4.https://segmentfault.com/a/1190000002797606#articleHeader6

  5.http://www.udpwork.com/item/12552.html

  6.https://www.cnblogs.com/wangzhisdu/p/7837726.html

Nginx反向代理解决iframe跨域问题的更多相关文章

  1. 项目部署问题:xftp无法连接服务器、Nginx403 Forbidden解决、nginx反向代理解决前端跨域问题

    一.xftp无法连接服务器 在xftp中配置正确的ip,用户名和密码后,居然无法连接 解决方案:将协议里面的FTP换成SFTP,注意换成SFTP后端口就默认换成22,要还是原来的21就还是连不上的哈 ...

  2. nginx反向代理-解决前端跨域问题

    1.定义 跨域是指a页面想获取b页面资源,如果a.b页面的协议.域名.端口.子域名不同,所进行的访问行动都是跨域的,而浏览器为了安全问题一般都限制了跨域访问,也就是不允许跨域请求资源.注意:跨域限制访 ...

  3. 使用nginx反向代理解决前端跨域问题

    1. 首先去Nginx官网下载一个最新版本的Nginx,下载地址:http://nginx.org/en/download.html.我这里下载的版本是:nginx/Windows-1.12.0.下载 ...

  4. 简单配置nginx反向代理,实现跨域请求

    简单配置nginx去做反向代理,实现跨域请求 简单介绍nginx的nginx.conf最核心的配置,去做反向代理,实现跨域请求. 更多详细配置,参考nginx官方文档 先介绍几个nginx命令 打开n ...

  5. 利用nginx做反向代理解决前端跨域问题

    最近朋友再群里提了一个问题,他们公司给他提供了一个获取数据的接口,在浏览器访问这个接口能获取到json数据,但是放在项目里使用ajax就产生了跨域问题,一般这个需要提供接口的后台方面需要做跨域处理,但 ...

  6. nginx 反向代理,支持跨域,前后分离

    前端开发往往涉及到跨域问题,其中解决方案很多: 1.jsonp 需要目标服务器配合一个callback函数. 2.window.name+iframe 需要目标服务器响应window.name. 3. ...

  7. Nginx反向代理配置可跨域

    由于业务需要,同一项目中的前端代码放在静态环境中,而后端代码放在tomcat中,但此时问题却出现了:前端使用ajax请求后端获取数据时出现如下报错 XMLHttpRequest cannot load ...

  8. nginx 配置反向代理解决请求跨域问题

    server { listen ; server_name localhost; #charset koi8-r; #access_log logs/host.access.log main; roo ...

  9. 使用webpack-dev-server设置反向代理解决前端跨域问题

    webpack-dev-server是一个小型的Node.js Express服务器,它使用webpack-dev-middleware来服务于webpack的包,除此自外,它还有一个通过Sock.j ...

随机推荐

  1. An annotation based command line parser

    Java命令行选项解析之Commons-CLI & Args4J & JCommander http://rensanning.iteye.com/blog/2161201 JComm ...

  2. repr调试python程序

    一般调试程序的时候都比较倾向print,利用直接打印的方法作出判断,但是print只能打印出结果,对类型无法作出判断.例如: a = 5 b = ' print(a) print(b) 结果为: 5 ...

  3. 2. 网友对app后端写作系列文章的写作建议

    很感谢"app后端"qq群的网友,在发布消息后,就收到了大量网友的反馈 下面的建议会融入到写作当中: 1.还有,对版本升级很感兴趣,我们现在为了兼容旧版本,已经把工程代码搞的乱哄哄 ...

  4. 面试时怎样回答:你对原生ajax的理解

    很多人跟我一样用习惯了jq封装好的$.ajax,但是面试时,原生ajax是很多面试官喜欢问的问题,今天再查资料,打算好好整理一下自己理解的原生ajax. 首先,jq的ajax:一般我常用的参数就是这些 ...

  5. 开机进入grub命令行之后。。。。

    最近由于经常整理自己电脑上的文件,难免都会遇到误删系统文件或者操作失误导致系统不能够正常进入的情况.这时就会出现grub错误的提示,只能输入命令才能进入系统.那么该输入什么命令呢?其实非常简单. gr ...

  6. Go 语言之三驾马车

    interface Go是一门面向接口编程的语言,interface的设计自然是重中之重.Go中对于interface设计的巧妙之处就在于空的interface可以被当作"Duck" ...

  7. bzoj5153&uoj348 【WC2018】州区划分

    五十分就是裸的O(3^n)子集dp. $$f[S]*{w[S]^{p}}=\sum_{T \in S}{f[T]*{w[S-T]^{p}}}$$ 然后我们考虑优化这个dp,我们发现这是子集卷积的形式, ...

  8. js的赋值问题:值传递还是引用传递?

    ECMAScript中有5种简单数据类型(也称为基本数据类型):Undefined.Null.Boolean.Number和String.还有1种复杂数据类型--Object,Object本质上是由一 ...

  9. C# WinForm ShowInTaskbar Api Version

    using System; using System.Runtime.InteropServices; namespace x { unsafe class NativeWindow { /* * W ...

  10. Python并发编程之初识异步IO框架:asyncio 上篇(九)

    大家好,并发编程 进入第九篇. 通过前两节的铺垫(关于协程的使用),今天我们终于可以来介绍我们整个系列的重点 -- asyncio. asyncio是Python 3.4版本引入的标准库,直接内置了对 ...