Refused to display 'https://www.xxx.com' in a frame because it set 'X-Frame-Options' to 'sameorigin'.
<iframe src='https://www.xxx.com' />
前言
又是同样的场景... 今天在领完盒饭,吃饭的时候,为了赶进度,不得不一边吃饭,一边敲代码,这时为了一个iframe嵌套第三方网站,就写了一个<iframe>标签,结果竟然发现报错了!!!,错误如下:
Refused to display 'https://www.xxx.com' in a frame because it set 'X-Frame-Options' to 'sameorigin'.

X-Frame-Options事故的原因全由他而起... 如下图:

在http请求的Response Headers中携带了x-frame-options: SAMEORIGIN。MDN上说HTTP 响应头是用来给浏览器 指示允许一个页面 可否在<frame>, <iframe>, <embed> 或者 <object>中展现的标记。站点可以通过确保网站没有被嵌入到别人的站点里面,从而避免clickjacking (维基百科竟然没有解释...) 攻击。
首先,X-Frame-Options 有三个可能的值:
X-Frame-Options: deny
X-Frame-Options: sameorigin
X-Frame-Options: allow-from https://example.com/
deny:
表示该页面不允许在frame中展示,即便是在相同域名的页面中嵌套也不允许。
sameorigin:
表示该页面可以在相同域名页面的 frame 中展示。
allow-from uri:
表示该页面可以在指定来源的 frame 中展示。
前端尝试解决
方案一:
x-frame-bypass
参考链接:
<script src="https://unpkg.com/@ungap/custom-elements-builtin"></script>
<script type="module" src="https://unpkg.com/x-frame-bypass"></script>
<iframe is="x-frame-bypass" src="https://example.org/"></iframe>
X-Frame-Bypass is a Web Component, specifically a Customized Built-in Element, which extends an IFrame to bypass the X-Frame-Options: deny/sameorigin response header. Normally such headers prevent embedding a web page in an element, but X-Frame-Bypass is using a CORS proxy to allow this.
它写着X-Frame-Bypass is using a CORS proxy to allow this,激动的心都快跳出来了,赶紧试了一把...结果页面真加载出来了,可是加载速度却慢的闪瞎双眼...
扒了扒源码...
fetchProxy (url, options, i) {
const proxy = [
'https://cors.io/?',
'https://jsonp.afeld.me/?url=',
'https://cors-anywhere.herokuapp.com/'
]
return fetch(proxy[i] + url, options).then(res => {
if (!res.ok)
throw new Error(`${res.status} ${res.statusText}`);
return res
}).catch(error => {
if (i === proxy.length - 1)
throw error
return this.fetchProxy(url, options, i + 1)
})
}
发现竟然是挂了个代理,代理服务器估计还是海外的,页面是正常打开了,估计代理是国外的,数据返回巨慢无比...还有一堆的issues处于open状态...想想还是算了吧...
方案二:
既然纯前端无法解决这个问题...那能不能绕个弯解决呢...
解决方案:第一步将不能跨域访问的url的host设置为你网站的域名,这一步是为了即使浏览器对url发起请求,因为host是你服务器的域名,请求也会进入到你的服务器;第二步:配置Nginx转发,将该url对应的请求的头部,加上more_clear_headers: x-frame-options,去掉响应头里的x-frame-options限制。这样就类似于模拟了从浏览器空页面直接访问的效果,规避了同源限制。第二步的Nginx方案等都是为了修改请求头,也可以使用Node做中间件,去修改请求头
乍一想,感觉这个方法真香...随手就起了个nginx
<iframe src='http://www.自己网站.com?url=https://www.xxx.com' />
这么一搞,还真的访问到了...可是,要展示的页面里有无数个<a>标签,<a href="/xxx">,链接都没有带域名,点击只有又跳转到了自己的域名下面...此时,内心又泛起了无数的波澜...
眼看着午饭由热变凉,由凉变坨...
如果谁有好的解决方案,请留言,我必感激不尽...在线等...挺急的...