【问题标题】:JavaScript not executed in WKWebViewJavaScript 未在 WKWebView 中执行
【发布时间】:2018-05-03 09:58:14
【问题描述】:

由于我对这个有点疯狂,我决定再试一次并在这里发布。

所以...

我有一个简单的 Swift/Cocoa 应用程序,其中包含 WKWebView

我加载了一个本地 HTML 文件(连同其余的 .css/.js 依赖项一起被复制到 /web 文件夹内的包中)。

这是完整的代码:

<!DOCTYPE html>
<html>
    <head>
        <title>IBAN Validator</title>
        <meta name="viewport" content="width=device-width"/>
        <meta charset="UTF-8">

        <link href="style/font-awesome.min.css" type="text/css" rel="stylesheet"/>
        <link href="style/electriq.css" type="text/css" rel="stylesheet"/>
        <link href="style/custom.css" type="text/css" rel="stylesheet" />
    </head>
    <body>
        <!-- window/ -->
        <div class="window">
            <div class="content" style="text-align: center">
                <div class="panel">
                    <input id="iban" type="text" style="text-align:center;"><br/>
                    <div style="position: relative; max-width: 150px; width: 100%; margin: 0 auto">
                        <a id="validateButton" href="#" class="button" style="width:150px;">Validate</a>
                        <span id="resultValid" style="position:absolute; left: calc(100% + 20px); top: 10%; color: green; font-size: 20px; display:none;"><i class="fa fa-check"></i></span>
                        <span id="resultInvalid" style="position:absolute; left: calc(100% + 20px); top: 10%; color: red; font-size: 20px; display:none;"><i class="fa fa-close"></i></span>
                    </div>
                </div>
            </div>
        </div>
        <!-- /window -->

        <div id="loader_overlay" style="padding-top:10%">
            <i class="fa fa-circle-o-notch fa-spin fa-3x fa-fw"></i><br/>
        </div>

        <!-- scripts/ -->
        <script>if (typeof module === 'object') {window.module = module; module = undefined;}</script>
        <script src="jquery.min.js" type="text/javascript"></script>
        <script>
            if (typeof window.jQuery !== 'undefined') {
                window.document.getElementById("loader_overlay").innerHTML += ".";
            } else {
                window.document.getElementById("loader_overlay").innerHTML += "x";
            }
        </script>
        <script src="handlebars.min.js" type="text/javascript"></script>
        <script>
            if (typeof window.Handlebars !== 'undefined') {
                window.document.getElementById("loader_overlay").innerHTML += ".";
            } else {
                window.document.getElementById("loader_overlay").innerHTML += "x";
            }
        </script>
        <script src="bridgecommander.js" type="text/javascript"></script>
        <script>
            if (typeof window.BridgeCommander !== 'undefined') {
                window.document.getElementById("loader_overlay").innerHTML += ".";
            } else {
                window.document.getElementById("loader_overlay").innerHTML += "x";
            }
        </script>
        <script src="iban.js" type="text/javascript"></script>
        <script>
            if (typeof window.IBAN !== 'undefined') {
                window.document.getElementById("loader_overlay").innerHTML += ".";
            } else {
                window.document.getElementById("loader_overlay").innerHTML += "x";
            }
        </script>
        <!-- <script src="app.js" type="text/javascript"></script> -->
        <script>

            // Generated by CoffeeScript 2.0.2
            var doValidate;

            window.appLoaded = true;
            window.document.getElementById("loader_overlay").innerHTML += ".";
            BridgeCommander.call("echo", "Before: onload");
            window.document.getElementById("loader_overlay").innerHTML += ".";

            window.onload = function() {
              BridgeCommander.call("echo", "Inside: onload");
              document.getElementById("loader_overlay").style.display = 'none';
              return $("#validateButton").on("click", doValidate);
            };
            window.document.getElementById("loader_overlay").innerHTML += ".";
            BridgeCommander.call("echo", "After: onload");

            doValidate = function() {
              var iban, valid;
              iban = $("#iban").val();
              valid = IBAN.isValid(iban);
              if (valid) {
                $("#resultValid").show();
                $("#resultInvalid").hide();
                $("#validateButton").removeClass("invalid").addClass("valid");
                BridgeCommander.call("echo", `Validating: ${iban}, Result: valid`);
              } else {
                $("#resultValid").hide();
                $("#resultInvalid").show();
                $("#validateButton").removeClass("valid").addClass("invalid");
                BridgeCommander.call("echo", `Validating: ${iban}, Result: invalid`);
              }
              setTimeout(function() {
                $("#validateButton").removeClass("valid").removeClass("invalid");
                $("#resultValid").hide();
                return $("#resultInvalid").hide();
              }, 3000);
              return false;
            };
            window.document.getElementById("loader_overlay").innerHTML += ".";

            if (typeof window.appLoaded !== 'undefined') {
                window.document.getElementById("loader_overlay").innerHTML += ".";
            } else {
                window.document.getElementById("loader_overlay").innerHTML += "x";
            }
        </script>
        <script>if (window.module) module = window.module;</script>
        <!-- /scripts -->
    </body>

</html>

重要提示: 这里(意思是在我的 Mac 上 - 以及我尝试过的每个人的 10.3.1 的 Mac)一切正常。当我将完全相同的二进制文件上传到 App Store 进行审查时,我不断收到相同的“错误”屏幕截图,这表明我最后一个 &lt;script&gt;&lt;/script&gt; 块中的任何代码都没有被执行。 (在window.appLoaded = true 部分之后)


会发生什么?我确实尝试过任何方法来调试它(因此,无数的 window.document.getElementById 事情,添加点以确保一切正常),但仍然没有。

如您所见,我正在加载几个脚本(根据我的测试加载正常),并且我还有几段内联 JS 代码(仍然可以正常工作)。除了最后一个! (无论如何,即使来自外部文件,它似乎也拒绝加载......)

再次,我考虑过缓存某事,我不知道,但我提醒您,它 - 显然 - 除了审查团队的机器外,它在任何地方都可以工作:S

欢迎任何想法!


P.S.如果有什么不清楚的地方,请随时问我


更新:(2017 年 11 月 28 日)用一个简单的 - 老式 - WebView 尝试了整个事情(以防它与 WKWebView 有关),仍然是我的应用程序被拒绝。或者更准确地说,我的应用程序(完全一样的版本,一切都一样)在任何地方都运行良好,除了审查它的人。

【问题讨论】:

  • 你能检查二进制文件是否包含所有需要的资源吗?
  • 包含您提到的错误屏幕截图是否相关?附带说明一下,我通常会看到评论是在 iPad 上完成的(如果应用程序不是通用的,则在兼容模式下),所以请确保您也已经在它们上进行了测试。
  • @paulvs 截图只是一个加载图标,下方有 4 个点。意味着在打印这四个点后调试停止。此外,该应用程序是 macOS 应用程序。
  • 如果您的代码必须仅适用于这些操作系统之一,您应该添加标签 osx 或 macOS-sierra o high-sierra。用你很少的信息来重现你的错误真的很难。你使用什么版本的 Swift?另外,什么是BridgeCommander?是第三方库吗?人们应该能够重现您的错误。
  • 创建外部 javascript 文件。找到缓存的 .js 文件比查找缓存的 .html 文件要好得多。

标签: javascript swift macos cocoa webview


【解决方案1】:

这可能是因为浏览器不知道如何解析脚本标签的内容

&lt;script&gt;&lt;/script&gt; 标签需要type 属性,大多数浏览器会假设它与最后一个相同,但因为您的代码中没有包含script 标签指定它可能不知道如何解析它们的类型@ 987654324@ 支持的不仅仅是 javascript,例如 VBScript,每当您为 javascript 打开 &lt;script&gt; 时,它应该是 &lt;script type="text/javascript"&gt;

另一个问题可能是window.onload 我建议您将其更改为DOMContentLoaded 事件并使用闭包来确保它执行代码。

那么为什么不将 jQuery 加载到应该加载它的 head 标记中,将 &lt;script src="jquery.min.js" type="text/javascript"&gt;&lt;/script&gt; 移动到 &lt;head&gt;&lt;/head&gt; 内部。

如果你有 jQuery,那么接下来为什么要混合使用 jQuery 和纯 Javascript 如果你有 jQuery,使用它的代码更小更干净

 (function($){
     $(function(){
         window.appLoaded = true;
         $("loader_overlay").append(".");
         BridgeCommander.call("echo", "Before: onload");
         $("loader_overlay").append(".");

         $("loader_overlay").append(".");
         BridgeCommander.call("echo", "After: onload");

         function doValidate() {
             var iban, valid;
             iban = $("#iban").val();
             valid = IBAN.isValid(iban);
             if (valid) {
                 $("#resultValid").show();
                 $("#resultInvalid").hide();
                 $("#validateButton").removeClass("invalid")
                                     .addClass("valid");
                 BridgeCommander.call("echo", `Validating: ${iban}, Result: valid`);
             } else {
                 $("#resultValid").hide();
                 $("#resultInvalid").show();
                 $("#validateButton").removeClass("valid")
                                     .addClass("invalid");
                 BridgeCommander.call("echo", `Validating: ${iban}, Result: invalid`);
             }

             setTimeout(function() {
                 $("#validateButton").removeClass("valid")
                                     .removeClass("invalid");
                 $("#resultValid").hide();
                 return $("#resultInvalid").hide();
             }, 3000);
             return false;
        };

         (function(doValidate) {
             BridgeCommander.call("echo", "Inside: onload");
             $("loader_overlay").css("display",'none');
             return $("#validateButton").on("click", doValidate);
         })(doValidate);

         window.document.getElementById("loader_overlay").innerHTML += ".";

         if (typeof window.appLoaded !== 'undefined') {
             window.document.getElementById("loader_overlay").innerHTML += ".";
         } else {
             window.document.getElementById("loader_overlay").innerHTML += "x";
         }
         if (window.module){ module = window.module; }
    });
});

另一方面,请摆脱所有文件加载检查。所以以下所有代码块

if (typeof window.Handlebars !== 'undefined') {
    window.document.getElementById("loader_overlay").innerHTML += ".";
} else {
    window.document.getElementById("loader_overlay").innerHTML += "x";
}

它们仅在调试时需要,如果文件加载到它加载的所有文件上,您就知道它是 Web Kit。所以您不需要这些检查,它们只是在使用电话处理能力并无缘无故地向您的应用程序添加工作。除了放一个 .在叠加层中...

同样,所有&lt;script src=... 都应该在&lt;head&gt; 标签内,在这种情况下,你的所有代码都应该在脚本标签内,并像我上面的版本一样使用 jQuery 读取。

您如何在 Mac 上测试此应用程序您是否使用 iPhone 模拟器?或真正的 iPhone 来测试我总是会推荐后者。并且您是否在其中一个上进行了测试,因为您似乎没有说您有,如果没有在您的开发人员帐户上注册用于测试的设备,请创建测试和构建测试版本的密钥,然后使用 Safari 或 chrome 远程调试工具在 WebView 上并确保一切正常。

【讨论】:

  • 马丁,非常感谢您的回答。但是,您提到的大多数案例都已经过测试。当审查团队的人向我发送他们的屏幕截图(也就是它不起作用)时,调试部分可以提供帮助 - 所以我正在打印一些......无害的点和 x 以从中做出一些东西。附言有问题的应用程序不是 iOS 应用程序。它适用于 macOS。
  • @Dr.Kameleon 好的,您应该仍然可以打开远程调试,这样您就可以将 WebKit 检查器连接到您的应用程序。如果您从 XCode 运行测试应用程序,它是否在您的系统上正常工作?如果这是仅 WebView 的应用程序,则可能值得尝试 Cordova 并将您的桥代码包装在 Cordova 的包装器中,它可能只是正常运行。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-13
  • 1970-01-01
  • 2013-11-07
相关资源
最近更新 更多