vue2-Django3-iframe解决方案,处理安全策略,事件拦截,处理iframe重载等

目录

简介

实现iframe

后端安全策略

通过Ngnix代理实现SAMEORIGIN

iframe的事件拦截,自定义处理

iframe的状态保持(解决vue中iframe重载)

解决方法


简介

Iframe(内联框架)是一种HTML元素,用于在网页上嵌入另一个HTML文档。然而,出于安全考虑,浏览器实施了同源策略,这意味着来自不同源的文档不能通过JavaScript互相交互。

实现iframe

<template><div><el-card class='container-card-second' v-loading='loading' element-loading-text='加载中...'><iframeid='iframeId'ref='myIframe'@load='handleIframeLoad'class='iframe-container':src='url'width='100%'frameborder='0'allowfullscreen></iframe></el-card></div>
</template>

然后可以通过响应式完成url的切换

 mounted() {this.url = "http://localhost:8080";}

后端安全策略

在Django/settings.py中有相关iframe的安全设置

# 定义iframe允许跨域请求的域名列表
# X_FRAME_OPTIONS = 'ALLOW-FROM http://localhost:8080/ http://192.168.252.227:8081/'# X_FRAME_OPTIONS = 'ALLOW-FROM http://192.168.252.227:8081'
X_FRAME_OPTIONS = 'SAMEORIGIN'

Django的X_FRAME_OPTIONS配置项用于设置HTTP响应头X-Frame-Options,这有助于防止点击劫持攻击。以下是X_FRAME_OPTIONS的作用和案例:

  1. 作用:X-Frame-Options是一个HTTP响应头,用来指示浏览器是否允许页面在<frame><iframe><embed><object>中被展示。通过设置这个头,网站可以确保自己的内容不被嵌入到其他网站中,从而避免点击劫持攻击。1

  2. 默认设置:Django默认启用了XFrameOptionsMiddleware中间件,该中间件会为每个响应设置X-Frame-OptionsDENY,意味着页面不能在任何框架中被展示。1

  3. 全局设置:可以通过在Django的设置文件中设置X_FRAME_OPTIONS变量来改变全局的X-Frame-Options值。例如,将其设置为SAMEORIGIN,允许页面在相同源的框架中被展示。

  4. 局部设置:通过ALLOW-FROM可设置自定义的网址,但是没有SAMEORIGIN好用。

ALLOW-FROMSAMEORIGINX-Frame-Options HTTP响应头的两个不同的指令,它们控制页面是否可以在<frame><iframe><embed><object>中被展示,但它们的应用范围和安全性有所不同:

  1. SAMEORIGIN:

    • SAMEORIGIN指令告诉浏览器只允许来自同一个源(即相同的协议、域名和端口)的页面在框架中展示当前页面。

    • 这个指令提供了一定程度的安全性,因为它限制了页面只能在相同源的上下文中被加载,从而避免了跨站点的点击劫持攻击。

    • 然而,如果网站有多个子域,并且需要在这些子域之间共享内容,SAMEORIGIN可能不够灵活。

  2. ALLOW-FROM(注意:并非所有浏览器都支持):

    • ALLOW-FROM指令允许指定页面可以在来自特定来源的框架中展示。这需要指定一个具体的URL。

    • 例如,如果设置为ALLOW-FROM https://example.com,那么只有来自https://example.com的页面才能在框架中展示当前页面。

    • 这个指令提供了更细粒度的控制,允许网站与特定的合作伙伴或服务共享内容,同时仍然保持较高的安全性。

区别:

  • SAMEORIGIN是一个更保守的策略,适用于大多数情况,因为它只允许相同源的页面加载。

  • ALLOW-FROM提供了更细粒度的控制,但需要谨慎使用,因为它可能会引入安全风险,特别是如果允许的来源不够安全或被恶意利用。

请注意,ALLOW-FROM并不是所有浏览器都支持,而且它的使用可能会更加复杂,因为需要正确地指定允许的来源。相比之下,SAMEORIGIN是一个更广泛支持且更安全的选项。在实际使用中,应根据具体需求和安全考虑来选择合适的指令。

通过Ngnix代理实现SAMEORIGIN

首先vue开发的前端一般都会使用ngnix代理,那么只需要新增一个在此端口下新增一个path用于代理你的iframe的内部页面。

例如

		server {listen       8081;server_name  localhost;location /api {#需要代理访问的后端服务器地址proxy_pass http://localhost:8000;#重写以/api为baseURL的接口地址rewrite "^/api/(.*)$" /$1 break;}}

根据上述配置:

如果你将 iframe 内容通过 Nginx 代理设置在 8081/api,并且你的前端页面也是通过 8081 端口提供服务的,那么即使实际内容来自于后端服务(假设是 8000 端口),从浏览器的角度来看,这些请求都是发往同一个源(即 localhost:8081)。

在这种情况下,当浏览器对 iframe 请求执行同源策略检查时,它会认为所有请求都是从同一个源发起的,因为它们都有相同的协议(例如 http)、域名(例如 localhost)和端口号(8081)。所以,在这种配置下,就算实际上 iframe 的内容是由不同端口的后端服务生成的,由于浏览器只能"看到" 8081 端口,X-Frame-Options 设为 SAMEORIGIN 是可以工作的,因为它满足了从同一来源加载 iframe 内容的要求

Nginx首先将请求转发到http://localhost:8000

接着,rewrite指令将请求的URI从/api/users重写为/users

最终,后端服务将收到不带有/api前缀的请求路径,即/users

那么你就可以通过http://你的项目ip:8081/api 来访问你的iframe网页

至此若你的iframe是内部网页则可以通过此方案实现SAMEORIGIN

iframe的事件拦截,自定义处理

使用@load='handleIframeLoad'和ref='myIframe'

addEvent(iframe) {iframe.contentWindow.document.addEventListener('click', event => {// 获取超链接的href属性const href = event.target.href;// 定义你希望拦截并使用Vue路由处理的URL部分const mark_val = '/xxx_edit';// 如果href包含mark_val,则进行Vue路由导航if (href.includes(mark_val)) {// 阻止默认行为event.preventDefault();// 提取ID或其他必要的路由参数const id = href.split('/').pop();// 使用Vue路由进行导航this.$router.push(`${mark_val}/${id}`);}// 若不符合特定条件,则不阻止默认行为,链接将按原本方式跳转});},handleIframeLoad() {const iframe = this.$refs.myIframe;if (iframe) {this.addEvent(iframe);}setTimeout(() => {this.loading = false;}, 1500);setTimeout(() => {this.addEvent(iframe);}, 3000);}

笔者增加延时是为了防止页面加载缓慢,没有成功绑定到事件。这里演示了拦截点击事件然后做处理。

iframe的状态保持(解决vue中iframe重载)

上述步骤都完成后,你可能会发现你的页面在子页面切换的时候总是会重载iframe的url。

1.Vue 的缓存机制并不是直接存储 DOM 结构,而是将 DOM 节点抽象成了一个个 VNode节点。因此,Vue 的 keep-alive 缓存也是基于 VNode节点 而不是直接存储 DOM 节点。在需要渲染的时候从Vnode渲染到真实DOM上。

2.iframe中keep-alive机制失效原因:iframe页里的内容并不属于节点的信息,所以使用keep-alive依然会重新渲染iframe内的内容。而且iframe每一次渲染就相当于打开一个新的网页窗口,即使把节点保存下来,在渲染时iframe页还是刷新的

解决方法

找到项目的路由入口,然后针对iframe页面做非keep-alive的处理。

以下为实例代码

            <div class='content'><transition name='move' mode='out-in'><!--                        isRouterAlive && !$route.meta.iframe 排除iframe页面的显示由下面的独立的iframe页面实现显示--><keep-alive :include='tagsList' :max='15'><router-view:key='$route.fullPath'ref='routerView'v-if='isRouterAlive && !$route.meta.iframe'/></keep-alive></transition><!--                独立的iframe页面;根据路由的fullPath(包括路由的参数 方便处理不同参数的同一个组件)判断是否显示--><component class='no-iframe-page'v-for='item in hasOpenComponentsArr':key='item.fullPath':is='item.name'v-show='$route.fullPath === item.path'></component></div>

其中逻辑部分为

    computed: {comTags() {return this.$store.state.globalTagsList;},/*** 利用全局响应式的标签列表过滤iframe页面,并且可以实现动态打开iframe页面* @returns*/hasOpenComponentsArr() {return this.comTags.filter(item => item.meta && item.meta.iframe);}}

globalTagsList是利用vuex(此处的使用方式参考点我查看)将标签页做了全局状态管理。

例如

        tagsList: {get() {return this.$store.state.globalTagsList;},set(value) {this.$store.commit('SET_GLOBAL_TAGS_LIST', value);}}

笔者通过路由的元信息来实现iframe页面的区分,以下为路由部分的代码实例

                {path: '/xxx/:id',component: resolve => require(['../views/xxx/xxx.vue'], resolve),meta: { title: 'xxx', iframe: true },name: 'xxx'}]

至此iframe页面可以完全作为整个web页面内的子页面来使用了。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/46433.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

周鸿祎为什么建议Java、前端、大数据、PHP开发都要学一下大模型?_ai大模型全栈工程师跟java有关吗

ChatGPT的出现在全球掀起了AI大模型的浪潮&#xff0c;2023年可以被称为AI元年&#xff0c;AI大模型以一种野蛮的方式&#xff0c;闯入你我的生活之中。 从问答对话到辅助编程&#xff0c;从图画解析到自主创作&#xff0c;AI所展现出来的能力&#xff0c;超出了多数人的预料&…

智慧公厕系统实现人性化与节能化的完美结合

在当今社会&#xff0c;科技的飞速发展正不断改变着我们的生活方式&#xff0c;公厕也不例外。智慧公厕系统的出现&#xff0c;不仅提升了人们的使用体验&#xff0c;更实现了人性化与节能化的完美结合&#xff0c;为城市公共服务带来了全新的变革。 一、人性化&#xff0c;是智…

echarts 实现水利计算模型-雨量,流量,时间分割线

需求背景解决效果ISQQW代码地址index.vue 需求背景 实现水利计算模型-雨量&#xff0c;流量&#xff0c;时间分割线 解决效果 ISQQW代码地址 链接 index.vue <!--/** * author: liuk * date: 2024/06/13 * describe: 洪水预报结果图表 */--> <template><di…

算法篇 滑动窗口 leetcode 长度最小的子数组

长度最小的子数组 1. 题目描述2. 算法图分析2.1 暴力图解2.2 滑动窗口图解 3. 代码演示 1. 题目描述 2. 算法图分析 2.1 暴力图解 2.2 滑动窗口图解 3. 代码演示

数据结构进阶——使用数组实现栈和队列详解与示例(C,C#,C++)

文章目录 1、数组实现栈栈的基本操作C语言实现C#语言实现 2、 数组实现队列队列的基本操作C语言实现C# 语言实现C语言实现 总结 在编程世界中&#xff0c;数据结构是构建高效算法的基石。栈和队列作为两种基本的数据结构&#xff0c;它们的应用非常广泛。本文将带领大家使用C&a…

股票质押约定购回:机制、风险与策略!

​股票质押约定购回&#xff1a;机制、风险与策略 在复杂的金融市场中&#xff0c;股票质押约定购回作为一种常见的融资手段&#xff0c;受到了众多投资者和企业的关注。本文将深入探讨股票质押约定购回的定义、运作机制、潜在风险以及投资者和企业在操作时应采取的策略。 一、…

HackChat匿名聊天室

匿名聊天 聊天室地址 这是一款极简、无干扰的聊天应用程序&#xff0c;可以让你专注于交流而不必担心干扰. 频道通过 url 创建、加入和共享&#xff0c;通过更改问号后的文本来创建自己的频道. hack.chat 服务器上不会保留任何消息历史记录&#xff0c;链接断开消息就会删除. …

尚硅谷大数据技术-数据湖Hudi视频教程-笔记03【Hudi集成Spark】

大数据新风口&#xff1a;Hudi数据湖&#xff08;尚硅谷&Apache Hudi联合出品&#xff09; B站直达&#xff1a;https://www.bilibili.com/video/BV1ue4y1i7na 尚硅谷数据湖Hudi视频教程百度网盘&#xff1a;https://pan.baidu.com/s/1NkPku5Pp-l0gfgoo63hR-Q?pwdyyds阿里…

基于5个K7的多FPGA PCIE总线架构的高性能数据预处理平台

板载FPGA实时处理器&#xff1a;XCKU060-2FFVA15172个QSFP光纤接口&#xff0c;最大支持10Gbps/lane板载DMA控制器&#xff0c;能实现双向DMA高速传输支持x8 PCIE主机接口&#xff0c;系统带宽5GByte/s1个R45自适应千兆以太网口1个FMC子卡扩展接口 基于PCIE总线架构的高性能数据…

DIY系列——自制简易笔记本电脑散热器

前言&#xff1a;为什么要自制笔记本电脑散热器&#xff1f; 夏天到了&#xff0c;电脑的使用频率也在增加。尤其是笔记本电脑&#xff0c;长时间运行后很容易发热&#xff0c;影响性能和寿命。市场上有很多散热器产品&#xff0c;但价格不菲且效果参差不齐。如果你动手能力强…

【原创】springboot+mysql图书共享交流平台设计与实现

个人主页&#xff1a;程序猿小小杨 个人简介&#xff1a;从事开发多年&#xff0c;Java、Php、Python、前端开发均有涉猎 博客内容&#xff1a;Java项目实战、项目演示、技术分享 文末有作者名片&#xff0c;希望和大家一起共同进步&#xff0c;你只管努力&#xff0c;剩下的交…

C++11空指针类型

C11之前&#xff1a;NULL 在C程序开发中&#xff0c;为了提高程序的健壮性&#xff0c;一般会在定义指针的同时完成初始化操作&#xff0c;或者在指针的指向尚未明确的情况下&#xff0c;都会给指针初始化为NULL&#xff0c;避免产生野指针问题。C98/03 标准中&#xff0c;将一…

gihub配置ssh key

检查本地主机是否已经存在ssh key cd ~/.ssh# 是否存在id_rsa和id_rsa.pub文件&#xff0c;存在则说明已有ssh Key ls生成ssh key ssh-keygen -t rsa -C "Your emailXXX.com"一直回车即可 获取公钥内容&#xff08;id_rsa.pub&#xff09; cd ~/.ssh cat id_rsa…

子数组问题

目录 最大子数组和 环形子数组的最大和 乘积最大子数组 乘数为正数的最长子数组长度 等差数列划分 最长湍流子数组 单词拆分 环绕字符串中唯一的子字符串 声明&#xff1a;接下来主要使用动态规划来解决问题&#xff01;&#xff01;&#xff01; 最大子数组和 题目 …

优化理论——迭代方法

线性回归建模 训练&#xff0c;预测 { ( x ( i ) , y ( i ) ) } \{(x^{(i)},y^{(i)})\} {(x(i),y(i))} ⼀个训练样本&#xff0c; { ( x ( i ) , y ( i ) ) ; i 1 , ⋯ , N } \{(x^{(i)},y^{(i)});i1,\cdots ,N\} {(x(i),y(i));i1,⋯,N} 训练样本集 { ( x 1 ( i ) , x 2 ( i…

Linux 扩展硬盘容量

根分区的硬盘容量不够了需要添加容量 扩展硬盘容量前提是需要虚拟机关机才能进行以下操作 在虚拟中找到虚拟机设置 >> 点击硬盘 >> 选择扩展 >> 输入自已要扩展的大小 >> 确定 这些设置好之后&#xff0c;启动虚拟机 fdisk /dev/sda n p 三个回车…

09、java程序流程控制之一:顺序结构、分支语句(if-else结构)(经典案例以及Scanner类的使用)

java程序流程控制之一&#xff1a; Ⅰ、顺序结构&#xff1a;1、顺序结构简介&#xff1a; Ⅱ、分支语句&#xff1a;if-else1、if-else分支结构&#xff1a;其一、描述&#xff1a;其二、代码为&#xff1a;其三、截图为&#xff1a; 2、如何从键盘获取不同类型的变量&#xf…

Mac Dock栏多屏幕漂移固定的方式

记录一下 我目前的版本是 14.5 多个屏幕&#xff0c;Dock栏切换的方式&#xff1a; 把鼠标移动到屏幕的中间的下方区域&#xff0c;触到边边之后&#xff0c;继续往下移&#xff0c;就能把Dock栏固定到当前屏幕了。

pytorch 是如何调用 cusolver API 的调用

0&#xff0c;环境 ubuntu 22.04 pytorch 2.3.1 x86 RTX 3080 cuda 12.2 1, 示例代码 以potrs为例&#xff1b; hello_cholesk.py """ hello_cholesky.py step1, Cholesky decompose; step2, inverse A; step3, Cholesky again; python3 hello_cholesky.py -…

【Hot100】LeetCode—155. 最小栈

目录 题目1- 思路2- 实现⭐155. 最小栈——题解思路 3- ACM 实现 题目 原题连接&#xff1a;155. 最小栈 1- 思路 思路 最小栈 ——> 借助两个栈来实现 2- 实现 ⭐155. 最小栈——题解思路 class MinStack {Stack<Integer> data;Stack<Integer> min;public …