移动端JS调用iframe方法的3种解决方案(含跨域通信与兼容处理)
你是不是遇到过这种情况?明明在电脑上跑得好好的JS调用iframe代码,一到手机端就各种报错...哎,这时候真想摔手机!别急,今天咱们就聊聊这个让新手抓狂的问题。我敢说,看完这篇,你至少能少加3天班——毕竟当年我为了搞懂这个,差点把键盘都砸了(苦笑)
先问个扎心的问题:为什么你用window.parent.document.getElementById拿不到iframe里的元素?其实啊,这和移动端浏览器内核、安全策略都有关系。下面我要说的这三种方法,保准比你在知乎搜到的"新手如何快速涨粉"那些水文实在多了!
第一种笨办法:直接通信法
最适合刚入门的小白,但有个致命缺点——??只能在同域名下使用??。具体怎么操作呢?
-
主页面这样写:
javascript复制
let iframe = document.getElementById('myFrame'); iframe.contentWindow.doSomething(); //直接调用子窗口方法
-
iframe页面里必须有:
javascript复制
function doSomething() { alert('成功啦!'); }
但等等!你可能要问:为什么我在安卓微信浏览器里测试总报错?这就是移动端常见的??跨进程通信阻塞??问题。解决方法很简单——在iframe加载完成后再操作:
javascript复制iframe.onload = function() { //这里才能安全调用 }
第二种黑科技:postMessage跨域
这才是解决跨域问题的正解!不过要注意数据格式,不然就像我当年那样,调试了5个小时发现少了个引号...
??发送方代码??:
javascript复制//主页面发送 iframe.contentWindow.postMessage('要传递的数据', 'https://目标域名'); //iframe内部发送 window.parent.postMessage('回传数据', '*');
??接收方必须加监听??:
javascript复制window.addEventListener('message', (e) => { if(e.origin !== '信任的域名') return; console.log(e.data); });
这里有个坑爹的地方——安卓7.0以下系统对postMessage的支持有问题。这时候就得用备用方案:
javascript复制//判断是否支持postMessage if(typeof window.postMessage === 'undefined') { //降级到URL传参方式 iframe.src += '?data=' + encodeURIComponent(你的数据); }
第三种野路子:代理页面中转
适合要兼容IE这种古董浏览器的情况。原理就像找中间人传纸条:
步骤分解:
- 主页面 => 代理页面(同域)
- 代理页面 => 目标iframe(不同域)
- 数据通过URL参数传递
不过这种方法有个致命缺陷——??数据量不能超过2KB??!所以最好只传关键参数:
javascript复制//主页面跳转代理页 location.href = 'proxy.html?action=submit&data=' + data; //代理页处理 let params = new URLSearchParams(location.search); iframe.src = 'https://目标域名?action=' + params.get('action');
常见问题答疑
Q:为什么用postMessage有时收不到消息?
A:八成是没校验origin!有次我忘了加校验,结果被恶意网站截胡了数据...
Q:iOS微信里iframe高度异常怎么办?
A:加这个meta标签保命:
html运行复制name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
Q:移动端滑动穿透怎么破?
A:在iframe外层套个div,加上这个CSS:
css复制.iframe-wrapper { touch-action: none; overflow: hidden; }
表格对比三种方法:
方法 | 跨域支持 | 数据量 | 兼容性 |
---|---|---|---|
直接通信 | 不支持 | 无限制 | 一般 |
postMessage | 支持 | 2MB以内 | 较好 |
代理页面 | 支持 | 2KB以内 | 极差 |
小编观点:新手建议先用postMessage练手,等项目上线前再用代理方案兜底。别学我当年非要装逼用高级API,结果上线当天被老板追着骂...(别问我怎么知道的)
本文由嘻道妙招独家原创,未经允许,严禁转载