解决iframe嵌套第三方页面被拒绝

背景

很多时候,出于安全考虑,没有第三方页面的允许,我们是无法直接通过iframe去打开别人的第三方页面的,通常他们会通过在页面请求的响应头增加X-Frame-Options (去了解)和Content-Security-Policy (去了解)。

目的

可是有些时候,为了满足一些比较变态的需求,就不得不去做一些违背安全的问题,比如需要嵌套一个github.com的页面等。

现象

直接使用会是如下的场景(我这里使用了本地代理,把真实请求代理到了某音平台,其实就是相当于嵌套别人第三方页面)
在这里插入图片描述

Refused to frame 'http://localhost:3000/' because an ancestor violates the following Content Security Policy directive: "frame-ancestors https://pc.xgo.bytedance.net https://tcs.bytedance.net https://*.douyin.com".

解决方案

  1. 如果你们所处的需求跟对方有合作,最好就是让对方给开通访问白名单,这样就可以解决,从技术角度就是
Content-Security-Policy frame-ancestors 加上自己的源地址
X-Frame-Options allow-from 加上自己的源地址
  1. 通过服务器代理来更改响应头字段,绕过浏览器的验证,这样也可以实现页面的嵌套 【不过这种不知道后续会不会被其他安全措施再次修复,目前看是还可以使用这种方案的】
    先看效果
    在这里插入图片描述

这里我的服务端使用了koa框架,直接上代码


const Koa = require('koa');
const Router = require('koa-router');
const request = require("request");
const querystring = require("querystring");
const url = require("url");

const app = new Koa();
const router = new Router();

/** 代理接口,用来修改响应头 */
router.get('/proxy',  (ctx) => {
    const originUrl = url.parse(ctx.req.url);
    const qs = querystring.parse(originUrl.query);
    const targetUrl = qs["target"];

    const options = {
        headers: {
            "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/128.0.0.0 Safari/537.36",
            "cookie": `有的 网站需要检测特定的cookie key`
        }
    };
    // 2.代发请求

    return new Promise((resolve, reject) => {
        request(targetUrl, options, (error, response, body) => {
            if (error) reject(error)
            if (!error && response.statusCode === 200) {
                
                ctx.res.writeHead(200, { "Content-Type": "text/html" })
                ctx.res.end(body)
                resolve();
            } else {
                ctx.response.body = {
                    status: response.statusCode,
                    result: 'forbidden'
                }
                resolve()
            }
        });
    });
})

app.use(router.routes());
app.use(router.allowedMethods())

const port = 10101;
// 1.创建代理服务
app.listen(port);

前端主要代码

<iframe id="byte-iframe" width="100%" height="100%" src='http://localhost:10101/proxy/?target=https%3A%2F%2Fwww.douyin.com%2Fdiscover' ref={refIframe}></iframe>

后续我会继续增对这块出续集,感兴趣的可以关注一下,我也会针对这一个主题,去尝试扩展一些骚操作,目前先保密

写到最后

如果有帮到大家,记得帮博主点个赞,你们的支持是我持续更新的最大动力啦

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值