3

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());
}

2 Answers 2

1

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;
    };
Sign up to request clarification or add additional context in comments.

Comments

0

for me the problem was with includes

 if (MY_STRING.includes("X1X")) {  // Error
     return true;
 }

then I used indexOf

 if (MY_STRING.indexOf("X1X") > 0 ) {
     return true;
 }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.