iframe在IOS下,样式变大BUG

博客指出iframe在IOS下加载富文本时,富文本内样式会变大,并非默认的16px。针对此问题给出解决方案,若高度固定,需判断手机类型,Android设scrolling为auto;若高度自适应,scrolling设为no,再用js动态适应富文本高度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

遇到问题:

iframe在IOS下,加载富文本,富文本内样式会变大,并不是默认的16px

解决方案:

iframe {
  width: 1px;
  min-width: 100%;
  *width: 100%;
}

同时iframe标签设置为

<!-- IOS为: -->
<iframe scrolling="no"></iframe>

若高度是固定的,则需判断手机类型为Android还是IOS,若为Android则讲scrolling改为auto

<!-- Android为: -->
<iframe scrolling="auto"></iframe>

若iframe的高度为自适应,则scrolling为no,在通过js动态适应富文本高度

setIframeHeight(iframe) {
      let _this = this
      if (iframe) {
        let iframeWin = iframe.contentWindow || iframe.contentDocument.parentWindow;
        if (iframeWin.document.body) {
          let imgs = iframeWin.document.getElementsByTagName("img");
          for (let i = 0; i < imgs.length; i++) {
            imgs[i].style.maxWidth = "100%";
          }
          let a, b, c = 0;
          let timer = setInterval(function() {
            if (c == 1) {
              a = iframeWin.document.body.scrollHeight || iframeWin.document.body.scrollHeight;
            } else if (c == 10) {
              b = iframeWin.document.body.scrollHeight || iframeWin.document.body.scrollHeight;
              if (a == b) {
                clearInterval(timer);
              }
              c = 0;
            }
            c++;
            iframe.style.height = iframeWin.document.body.scrollHeight + "px" || iframeWin.document.documentElement.scrollHeight + "px";
          }, 800);
        }
      }
    }
<think>问题:UniApp 内嵌 iframeiOS 中不运行嵌入的 HTML 的 JS 方法 原因分析:iOS 的 WKWebView 有严格的安全策略,特别是跨域和文件访问限制,导致 iframe 内的 JS 无法执行。 解决方案: 1. 使用 web-view 组件替代 iframe:在 App 端,使用原生 web-view 组件,它提供了更好的 JS 执行环境。 2. 配置 WKWebView 安全策略:在 manifest.json 中设置允许跨域访问。 3. 使用 postMessage 进行通信:通过 web-view 的 message 事件和 iframe 的 postMessage 实现跨域通信。 4. 确保 JS 在用户交互后执行:iOS 要求 JS 必须在用户交互(如点击)后触发,否则可能被阻止。 具体步骤: 步骤一:使用 web-view 组件(推荐) ```html <!-- 在 App 端使用 web-view --> <!-- #ifdef APP-PLUS --> <web-view :src="url" @message="onMessage"></web-view> <!-- #endif --> <!-- 在 H5 端使用 iframe --> <!-- #ifdef H5 --> <iframe :src="url" @load="onIframeLoad"></iframe> <!-- #endif --> ``` 步骤二:配置 manifest.json ```json "app-plus": { "wkwebview": { "preference": { "allowFileAccessFromFileURLs": true, "allowUniversalAccessFromFileURLs": true } } } ``` 步骤三:JS 方法调用示例(通过 postMessage) 在嵌入的 HTML 中,通过 postMessage 发送消息: ```javascript // 在 iframe 内部或外部网页中 parent.postMessage({ action: 'methodName', data: {} }, '*'); ``` 在 UniApp 页面中监听消息: ```javascript // 如果是 web-view onMessage(e) { const data = e.detail.data[0]; // 注意:web-view 的消息格式 if (data.action === 'methodName') { // 执行对应方法 } } // 如果是 H5 的 iframe mounted() { window.addEventListener('message', (e) => { if (e.data.action === 'methodName') { // 执行方法 } }); } ``` 步骤四:用户交互触发 在 iOS 上,如果 JS 是自动执行的,可能被阻止。需要绑定到用户交互事件(如按钮点击)上: ```html <button @click="runIframeJS">执行JS</button> ``` 步骤五:检查控制台错误 在 Safari 远程调试中查看是否有类似以下错误: - Blocked attempt to execute script because it is not triggered by user interaction. 完整示例: ```html <template> <view> <!-- #ifdef APP-PLUS --> <web-view :src="url" @message="onWebViewMessage"></web-view> <!-- #endif --> <!-- #ifdef H5 --> <iframe ref="iframe" :src="url"></iframe> <button @click="postToIframe">发送指令</button> <!-- #endif --> </view> </template> <script> export default { data() { return { url: 'https://your-domain.com/embedded.html' } }, methods: { // APP 端接收消息 onWebViewMessage(e) { const message = e.detail.data[0]; // 处理消息 }, // H5 端向 iframe 发送消息 postToIframe() { this.$refs.iframe.contentWindow.postMessage({ action: 'callJS' }, '*'); } } } </script> ``` 注意:如果嵌入的是第三方页面,可能无法修改其代码,此时需考虑其他方案,如使用服务端代理页面。 §§相关问题§§ 1. 如何在 UniApp 的 web-view 中调用嵌入页面的特定 JavaScript 函数? 2. iOS 的 WKWebView 有哪些安全策略会阻止 JavaScript 自动执行? 3. 使用 postMessage 通信时,如何确保跨域消息传递的安全性? 4. 如果嵌入的是第三方不可控页面,有哪些替代方案可以实现交互? 5. 在 UniApp 中,如何同时兼容 Android 和 iOS 实现 iframe 内的 JS 调用?</think>### UniApp 内嵌 iframeiOS 中不执行 JS 方法的解决方案 当 iOS 设备上 iframe 内容能显示但内嵌的 JavaScript 方法不执行时,通常是 iOS 安全策略阻止了 JS 执行。以下是关键解决方案: #### 核心问题原因 1. **iOS 安全策略限制** WKWebView 默认阻止跨域脚本执行,特别是第三方域的 JS 2. **用户交互要求** iOS 要求 JS 必须在用户手势事件(如点击)后触发 3. **沙箱限制** iframe 的 `sandbox` 属性可能过度限制了脚本执行 4. **通信协议问题** `postMessage` 通信未正确处理跨域消息 #### 解决方案 1. **启用 JS 执行权限(关键配置)** 在 `manifest.json` 中设置: ```json "app-plus": { "wkwebview": { "preference": { "allowFileAccessFromFileURLs": true, "allowUniversalAccessFromFileURLs": true, "javaScriptCanOpenWindowsAutomatically": true // 允许自动执行JS } } } ``` 2. **使用 web-view 替代 iframe 并添加通信通道** ```html <web-view :src="pageUrl" @message="handleMessage" @onPostMessage="handlePostMessage"> </web-view> ``` 3. **JS 方法触发机制改造** 将自动执行改为用户交互触发: ```javascript // 在嵌入的HTML中 document.getElementById('triggerBtn').addEventListener('click', () => { // 需要执行的JS方法 myFunction(); }); ``` 4. **跨域通信解决方案** 使用 `postMessage` 进行安全通信: ```javascript // 父页面 (UniApp) mounted() { uni.onWindowMessage(res => { if(res.data.action === 'callFunction') { // 执行对应方法 } }); } // 子页面 (iframe内) function callParentFunction() { window.parent.postMessage({ action: 'callFunction', params: {...} }, '*'); } ``` 5. **沙箱属性调整** 在 iframe 上添加允许脚本执行的沙箱属性: ```html <iframe sandbox="allow-scripts allow-same-origin" :src="pageUrl"> </iframe> ``` 6. **延迟执行机制** 在页面加载后延迟执行 JS: ```javascript // 在嵌入的HTML中 setTimeout(() => { if(window.activateFunctions) { window.activateFunctions(); } }, 1000); ``` #### 完整示例代码 ```html <!-- UniApp 页面 --> <template> <view> <!-- #ifdef APP-PLUS --> <web-view :src="safeUrl" @message="handleWebViewMessage" style="height: 80vh"> </web-view> <!-- #endif --> <!-- #ifdef H5 --> <iframe :src="safeUrl" @load="onIframeLoad" sandbox="allow-scripts allow-same-origin" style="height: 80vh"> </iframe> <!-- #endif --> <button @click="triggerJS">手动执行JS</button> </view> </template> <script> export default { data() { return { pageUrl: "https://your-domain.com/embedded-page.html" } }, computed: { safeUrl() { return this.pageUrl.replace("http:", "https:"); } }, methods: { // 处理web-view消息 handleWebViewMessage(e) { const msg = e.detail.data[0]; if(msg.type === 'executeFunction') { this[msg.functionName](...msg.args); } }, // 手动触发JS执行 triggerJS() { // #ifdef APP-PLUS const webView = uni.requireNativePlugin('DCWebView') webView.evalJavaScript(`window.activateFunctions()`) // #endif // #ifdef H5 document.querySelector('iframe').contentWindow.postMessage({ action: 'executeJS' }, '*'); // #endif }, // 需要执行的JS方法 customFunction(param) { console.log('JS方法执行成功', param); } } } </script> ``` #### 调试技巧 1. **iOS 远程调试**: - 启用 iOS 设备上的 Web 检查器(设置 > Safari > 高级) - 通过 macOS Safari 的「开发」菜单调试 WebView 2. **错误诊断**: ```javascript // 在嵌入页面添加错误监听 window.addEventListener('error', (e) => { console.error('JS执行错误:', e.message, e.filename, e.lineno); }); ``` 3. **通信验证**: ```javascript // 在嵌入页面添加消息监听 window.addEventListener('message', (e) => { if(e.data === 'ping') { window.parent.postMessage('pong', '*'); } }); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值