Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Android 5.0 WebView undefined is not a function error while running my JS script

I'm using JS script to get some data from Web page. I load this String which contains JS code.

 private static final String SCRAPE_SOME_DATA = "javascript:(function(){" +
            "var myJson;" +
            "var scrs = document.getElementsByTagName('script');" +
            "for(var i=0;i<scrs.length;i++) {" +                                                                     
            "try {" +                                                                                                   
            "if(Boolean(scrs[i].innerHTML) && scrs[i].innerHTML.startsWith('userLayer')) {" +                        
            "var al = scrs[i].innerHTML;" +
            "var s = al.indexOf('[');" +
            "if(s>-1) {" +                                                                                     
            "var e = al.indexOf('];', s+2);" +
            "myJson = al.substring(s,e+1);" +
            "}" +                                                                                             
            "break;" +
            "}" +                                                                                                                                                                                                   
            "} catch (e) {" +                                                                                
            "}" +                                                                                                    
            "}" +                                                                                                       
            "if(Boolean(myJson)) {" +
            "window." + SCRAPER + ".setUserLayer(myJson)" +
            "}" +
            "})();";

Then I load this code in my WebView

  webView.loadUrl(BookingScraper.SCRAPE_SOME_DATA);

Web page contuses a lot of tags 'script', I just need only one which name is userLayer. I get data from this layer convert to string and using @JavascriptInterface transfer got string to my Java method

        @JavascriptInterface
    public void setUserLayer(String userLayer) {
        if (userLayer != null) {
            try {
               Log.d("logs", userLayer);
            } catch (JSONException exception) {
                Crashlytics.log(dataLayer);
                Crashlytics.logException(exception);
            }
        }
    }

The problem is that at Android OS version 5.0 and 5.1 it does not work but for other version it's working OK. I debugged my JS and found out that the problem is in this part of code

scrs[i].innerHTML.startsWith('dataLayer')

JS throws Exception TypeError: Undefined is not a function. I have not idea why? Why it works for others Android OS version?

NOTICE: I've enabled

 webView.addJavascriptInterface(myScrapper, Mycraper.MY_SCRAPER);
    webView.getSettings().setDomStorageEnabled(true);
    webView.setWebChromeClient(new WebChromeClient());
    webView.setWebViewClient(new BookingWebViewClient());
}
like image 251
Alex Iachimov Avatar asked Jul 04 '26 23:07

Alex Iachimov


1 Answers

I ran into the same problem with older versions of Android. It looks like the WebView on those versions don't have String.prototype.startsWith or String.prototype.endsWith and need polyfills. I added the following 2 polyfills to my JS to fix it.

startsWith()

if (!String.prototype.startsWith) {
    String.prototype.startsWith = function(searchString, position){
        return this.substr(position || 0, searchString.length) === searchString;
    };
}

endsWith()

if (!String.prototype.endsWith)
    String.prototype.endsWith = function(searchStr, Position) {
        // This works much better than >= because it compensates for NaN:
        if (!(Position < this.length))
            Position = this.length;
        else
            Position |= 0; // round position
          return this.substr(Position - searchStr.length, searchStr.length) === searchStr;
    };
like image 67
Paul Avatar answered Jul 07 '26 13:07

Paul



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!