代码之家  ›  专栏  ›  技术社区  ›  Saidur Rahman

在Android中从内部html文件加载webview时javascript不工作

  •  0
  • Saidur Rahman  · 技术社区  · 7 年前

    当使用weblink加载webview时,JavaScript将正确加载,如:example.com/测试但是当webview从assets文件夹的内部html文件加载时,JavaScript不起作用。

    Html文件代码:

    <!DOCTYPE html>
    <html>
    <head>
        <meta charset="utf-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title>payment</title>
        <meta name="viewport" content="width=device-width, initial-scale=1">
    </head>
    <body>
    
    
    <!-- The Payment Form -->
    <form id="iframes" action="" method="GET">
        <div class="form-group">
            <label for="iframesCardNumber">Card Number:</label>
            <div class="iframeholder" id="iframesCardNumber"></div>
        </div>
        <div class="form-group">
            <label for="iframesCardExpiration">Card Expiration:</label>
            <div class="iframeholder" id="iframesCardExpiration"></div>
        </div>
        <div class="form-group">
            <label for="iframesCardCvv">Card CVV:</label>
            <div class="iframeholder" id="iframesCardCvv"></div>
        </div>
    
        <input type="submit" class="btn btn-primary" value="Submit" />
    </form>
    
    
    <!-- The SecureSubmit Javascript Library -->
    <script type="text/javascript" src="https://api2.heartlandportico.com/SecureSubmit.v1/token/2.1/securesubmit.js"></script>
    <!-- The Integration Code -->
    <script type="text/javascript">
      (function (document, Heartland) {
        // Create a new `HPS` object with the necessary configuration
        var hps = new Heartland.HPS({
          publicKey: '..............',
          type:      'iframe',
          // Configure the iframe fields to tell the library where
          // the iframe should be inserted into the DOM and some
          // basic options
          fields: {
            cardNumber: {
              target:      'iframesCardNumber',
              placeholder: '•••• •••• •••• ••••'
            },
            cardExpiration: {
              target:      'iframesCardExpiration',
              placeholder: 'MM / YYYY'
            },
            cardCvv: {
              target:      'iframesCardCvv',
              placeholder: 'CVV'
            }
          },
          // Collection of CSS to inject into the iframes.
          // These properties can match the site's styles
          // to create a seamless experience.
          style: {
            'input[type=text],input[type=tel]': {
                'box-sizing':'border-box',
               'display': 'block',
                'width': '100%',
                'height': '34px',
                'padding': '6px 12px',
                'font-size': '14px',
                'line-height': '1.42857143',
                'color': '#555',
                'background-color': '#fff',
                'background-image': 'none',
                'border': '1px solid #ccc',
                'border-radius': '4px',
                '-webkit-box-shadow': 'inset 0 1px 1px rgba(0,0,0,.075)',
                'box-shadow': 'inset 0 1px 1px rgba(0,0,0,.075)',
                '-webkit-transition': 'border-color ease-in-out .15s,-webkit-box-shadow ease-in-out .15s',
                '-o-transition': 'border-color ease-in-out .15s,box-shadow ease-in-out .15s',
                'transition': 'border-color ease-in-out .15s,box-shadow ease-in-out .15s'
            },
            'input[type=text]:focus,input[type=tel]:focus': {
                'border-color': '#66afe9',
              'outline': '0',
              '-webkit-box-shadow': 'inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)',
              'box-shadow': 'inset 0 1px 1px rgba(0,0,0,.075),0 0 8px rgba(102,175,233,.6)'
            },
            'input[type=submit]' : {
                        'box-sizing':'border-box',
                    'display': 'inline-block',
                  'padding': '6px 12px',
                  'margin-bottom': '0',
                  'font-size': '14px',
                  'font-weight': '400',
                  'line-height': '1.42857143',
                  'text-align': 'center',
                  'white-space': 'nowrap',
                  'vertical-align': 'middle',
                  '-ms-touch-action': 'manipulation',
                  'touch-action': 'manipulation',
                  'cursor': 'pointer',
                  '-webkit-user-select': 'none',
                  '-moz-user-select': 'none',
                  '-ms-user-select': 'none',
                  'user-select': 'none',
                  'background-image': 'none',
                  'border': '1px solid transparent',
                  'border-radius': '4px',
                  'color': '#fff',
                  'background-color': '#337ab7',
                  'border-color': '#2e6da4'
            },
            'input[type=submit]:hover':{
                    'color': '#fff',
                'background-color': '#286090',
                'border-color': '#204d74'
            },
            'input[type=submit]:focus, input[type=submit].focus':{
                'color': '#fff',
                'background-color': '#286090',
                'border-color': '#122b40',
                'text-decoration': 'none',
                'outline': '5px auto -webkit-focus-ring-color',
                        'outline-offset': '-2px'
            }
          },
          // Callback when a token is received from the service
          onTokenSuccess: function (resp) {
            alert('Here is a single-use token: ' + resp.token_value);
          },
          // Callback when an error is received from the service
          onTokenError: function (resp) {
            alert('There was an error: ' + resp.error.message);
          }
        });
    
        // Attach a handler to interrupt the form submission
        Heartland.Events.addHandler(document.getElementById('iframes'), 'submit', function (e) {
          // Prevent the form from continuing to the `action` address
          e.preventDefault();
          // Tell the iframes to tokenize the data
          hps.Messages.post(
            {
              accumulateData: true,
              action: 'tokenize',
              message: '........'
            },
            'cardNumber'
          );
        });
      }(document, Heartland));
    </script>
    </body>
    </html>
    

    我猜JavaScript中的css代码加载不正确。但当从示例网站链接加载时,它工作得很好,比如example.com/测试

    相关Java代码如下:

    public static String wikiLink = "file:///android_asset/test.html"
    
    ..............
    ..............
    .............
            WebSettings settings = webView.getSettings();
    
            //Using JavaScript in WebView, it will enable Javascript support for your website
            settings.setJavaScriptEnabled(true);
    
            //Zoom control
            settings.setBuiltInZoomControls(true);
            settings.setSupportZoom(true);
            settings.setDisplayZoomControls(false);
    
            //Handling Page Navigation
            webView.setWebViewClient(new WebViewClient() {
                @Override
                public boolean shouldOverrideUrlLoading(WebView view, String url) {
                    wikiLink = url;
                    view.loadUrl(url);
                    return true;
                }
    
                @Override
                public void onPageFinished(WebView view, String url) {
                    webView.setVisibility(View.VISIBLE);
                    layoutProgress.setVisibility(View.GONE);
                    progressBar.setIndeterminate(false);
                    super.onPageFinished(view, url);
    
                }
    
                @Override
                public void onPageStarted(WebView view, String url, Bitmap favicon) {
                    layoutProgress.setVisibility(View.VISIBLE);
                    progressBar.setIndeterminate(true);
                    super.onPageStarted(view, url, favicon);
                }
            });
            //End of Handling Page Navigation
    
            webView.setWebChromeClient(new WebChromeClient(){
                public boolean onJsAlert(WebView view, String url, String message, JsResult result) {
                    Log.d("LogTag", message);
                    result.confirm();
                    return true;
                }
            });
    
            webView.getSettings().setUserAgentString("Test");
            webView.getSettings().setCacheMode(WebSettings.LOAD_CACHE_ELSE_NETWORK);
            webView.getSettings().setDomStorageEnabled(true);
            webView.getSettings().setAllowUniversalAccessFromFileURLs(true);
    
            if(isOnline()) {
                if (webViewBundle == null) {
                    webView.loadUrl(wikiLink);
                } else {
                    webView.restoreState(webViewBundle);
                }
            } else {
                String summary = "<html><body><font color='red'>No Internet Connection</font></body></html>";
                webView.loadData(summary, "text/html", null);
                toast("No Internet Connection.");
            }
    

    如何解决这个问题?

    2 回复  |  直到 7 年前
        1
  •  1
  •   Sandesh Mankar    7 年前

    当我正在调用javascript函数时,页面可能还没有正确加载。

    我在WebView上添加了一个加载侦听器,如下所示

      mWebView.setWebViewClient(new WebViewClient() {
            @Override
            public void onPageFinished(WebView view, String url) {
                super.onPageFinished(view, url);
                if (url.equals("file:///android_asset/page.html")) {
                    mWebView.loadUrl("javascript:plot();");
                }
            }
        });
    

    现在每次通话都能正常工作。

    再次感谢您的关注!

        2
  •  1
  •   Oliver    7 年前

    我得到的问题是,在html源代码中的第一个“#”之后,webview“loadData”没有显示内容 在更新Chrome浏览器之前,一切都很好,sice update-我遇到了问题。

    从loadData改为loadDataWithBaseURL解决了这个问题

        3
  •  0
  •   Shane L.    6 年前

    Heartland JavaScript库需要通过HTTP/HTTPS方案而不是文件加载,因为它使用窗口.邮件用于在父窗口(您的WebView内容)和子iframe窗口之间通信的API。这是浏览器和Heartland库级别的一个限制,有助于安全和跨源资源共享(CORS)。

    解决这个问题的唯一方法是在Android应用程序中使用本机输入/控件。