iFrame重定向后URL获取异常:onload触发过早,如何获取最新URL
解决iframe重定向后无法获取最新URL的问题
这个问题我之前做项目时也踩过坑!iframe的onload事件确实只会在初始页面加载完成时触发,完全不管内部有没有跳转重定向,所以你之前的方法拿不到最终URL很正常。给你两个针对性的解决方案,根据你的场景选就行:
方案一:监听TP2的load事件(同域场景首选)
每次iframe内部完成一次页面加载(包括重定向后的页面),都会触发load事件。我们可以利用这一点,在每次触发时获取当前的实际URL,再更新TP3的地址:
// 先获取TP2的iframe元素 const tp2Frame = document.getElementById('tp2'); // 把用户输入的初始URL存下来,用来判断是否完成重定向 const initialTp2Url = tp2Frame.src; // 绑定load事件监听 tp2Frame.addEventListener('load', () => { try { // 获取TP2当前的最终URL(重定向后的) const currentTp2Url = tp2Frame.contentWindow.location.href; // 获取TP1的URL const currentTp1Url = document.getElementById('tp1').contentWindow.location.href; // 可选:如果只需要在重定向完成后执行一次,加个判断 if (currentTp2Url !== initialTp2Url) { // 更新TP3的源地址 document.getElementById("tp3").src = `http://example.com/load/kachi/#!/${currentTp1Url}$$${currentTp2Url}`; // 不想重复执行的话,这里可以移除监听 tp2Frame.removeEventListener('load', arguments.callee); } } catch (e) { console.error("获取URL失败,可能存在跨域问题:", e); } });
注意点:
- 用
contentWindow.location.href比contentDocument.location更可靠,前者在同域场景下能稳定获取当前页面URL; - 如果TP2有多次重定向,
load会触发多次,加初始URL的判断可以确保只在最终重定向完成后更新TP3; - 捕获异常是为了处理跨域场景(跨域时直接访问location会报错)。
方案二:使用postMessage传递URL(跨域场景必备)
如果TP2重定向后的页面和你的主页面不同域,浏览器的同源策略会阻止你直接获取iframe的location。这时候需要让TP2的最终页面主动把URL发送给主页面:
- 在TP2重定向后的页面中添加代码:
// 建议把*替换成你的主页面域名,比如"http://your-main-site.com",提升安全性 window.parent.postMessage( { type: 'tp2_redirect_done', url: window.location.href }, '*' );
- 在主页面中监听消息:
window.addEventListener('message', (event) => { // 验证消息来源,避免恶意网站发送的消息 if (event.origin !== 'https://tp2-final-domain.com') return; // 判断消息类型,确保是我们需要的TP2重定向完成通知 if (event.data.type === 'tp2_redirect_done') { const currentTp2Url = event.data.url; const currentTp1Url = document.getElementById('tp1').contentWindow.location.href; // 更新TP3的地址 document.getElementById("tp3").src = `http://example.com/load/kachi/#!/${currentTp1Url}$$${currentTp2Url}`; } });
注意点:
- 一定要验证
event.origin,防止恶意消息攻击; - 如果无法修改TP2重定向后的页面代码,这个方案就用不了,得和TP2的页面开发者沟通协作。
内容的提问来源于stack exchange,提问作者crosz




