背景
很多时候,出于安全考虑,没有第三方页面的允许,我们是无法直接通过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".
解决方案
- 如果你们所处的需求跟对方有合作,最好就是让对方给开通访问白名单,这样就可以解决,从技术角度就是
Content-Security-Policy frame-ancestors 加上自己的源地址
X-Frame-Options allow-from 加上自己的源地址
- 通过服务器代理来更改响应头字段,绕过浏览器的验证,这样也可以实现页面的嵌套 【不过这种不知道后续会不会被其他安全措施再次修复,目前看是还可以使用这种方案的】
先看效果
这里我的服务端使用了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>
后续我会继续增对这块出续集,感兴趣的可以关注一下,我也会针对这一个主题,去尝试扩展一些骚操作,目前先保密
写到最后
如果有帮到大家,记得帮博主点个赞,你们的支持是我持续更新的最大动力啦