React应用如何阻止跨域iframe内带_blank的a标签打开新标签页
解决方案
方案1:使用iframe的sandbox属性(最优实现,无额外代码)
跨域场景下无法直接操作iframe内部DOM,浏览器原生提供的sandbox属性是白名单权限控制机制,只要不给iframe开通弹窗权限,即可直接拦截所有内部新开标签页的行为,同时不会影响iframe内部按钮等元素的正常交互:
- 你只需在iframe标签上添加
sandbox属性,按需加入你地图功能需要的权限,故意不加入allow-popups权限即可,示例配置如下:
<iframe src="你的地图资源地址" frameborder="0" width="500px" height="500px" <!-- 按需添加需要的权限,不要加allow-popups即可 --> sandbox="allow-same-origin allow-scripts allow-forms" ></iframe>
- 常用的sandbox权限说明:
allow-same-origin:允许iframe加载的内容视为同源,可正常加载同源资源allow-scripts:允许iframe内部运行JavaScript(地图功能必须开启)allow-forms:允许iframe内部提交表单- 只要不添加
allow-popups,所有target="_blank"的a标签点击、window.open调用都会被浏览器直接拦截,不会弹出新标签页
方案2:重写父页面window.open(备用方案,适配特殊场景)
如果sandbox属性影响到你的地图核心功能无法正常使用,可以用该方案兜底:
iframe内部触发的target="_blank"跳转本质会调用顶层页面的window.open方法,你可以在React组件挂载时重写该方法,过滤掉来自iframe的弹窗请求,组件卸载时再恢复原方法即可:
useEffect(() => { const originalOpen = window.open; window.open = function(url, target, features) { // 过滤掉target为_blank的弹窗请求 if (target === '_blank') { // 直接返回null,阻止弹窗 return null; } // 其他请求正常放行 return originalOpen(url, target, features); }; // 组件卸载时恢复原方法,避免影响全局 return () => { window.open = originalOpen; }; }, []);
注意:该方案只会拦截
target="_blank"的弹窗,不会影响你应用内部的路由跳转,符合需求。
内容的提问来源于stack exchange,提问作者Mohit
相关产品推荐
相关产品推荐

