Webview bypass ssl error


#1

i develop an apps that can open website page directly without have to type some url so here is the code

<Page xmlns="http://schemas.nativescript.org/tns.xsd" navigatingTo="onNavigatingTo" class="page">
    <Page.actionBar>
        <ActionBar title="Portal Kanwil Kalbar" icon="">
			<!--
			<ActionItem tap="onReload" android.icon="res://reload" android.position="actionBar"/>
			-->
			<ActionItem tap="onReload" icon="res://reload" position="actionBar"/>
			<ActionItem tap="onBack" text="Halaman Sebelumnya" android.position="popup" visibility="{{ isKembali ? 'visible' : 'collapse' }}" />
			<ActionItem tap="onBrowser" text="Buka di Browser" android.position="popup"/>
			<ActionItem tap="onKeluar" text="Keluar" android.position="popup" />
        </ActionBar>
    </Page.actionBar>
<GridLayout>
         <WebView src="http://kalbar.kemenkumham.go.id" id="wv"></WebView>
    </GridLayout>
</Page>

the problem is web address is change to https it is become https://kalbar.kemenkumham.go.id and webview can’t open it. i know there is problem with it’s ssl. so how to solve it in android side?? i wanna pass ssl error and show the website page without have to confirm anything from user about ssl error. thanks for advance.


#2

I think you might have to override the default WebViewClient implementation here

Something similar to,

wv.android.setWebViewClient(new YourWebViewClientImpl());

#3

i’m stuck on it bro. please give clear example.


#4

@shafrudin Here is a working example how it could be implemented, but this is not perfect one you might need some cleanup.

I have taken the TypeScript hello world template and implemented this.

main-page.xml

<Page 
    xmlns="http://schemas.nativescript.org/tns.xsd" navigatingTo="navigatingTo" class="page">
    <Page.actionBar>
        <ActionBar title="My App" icon="" class="action-bar"></ActionBar>
    </Page.actionBar>
    <WebView id="webView" loaded="onWebViewLoaded"></WebView>
</Page>

main-page.ts

import { isAndroid } from 'platform';
import { EventData } from 'data/observable';
import { Page } from 'ui/page';
import { WebView } from 'ui/web-view';
import { HelloWorldModel } from './main-view-model';

let WebViewClient: any;

function initializeWebViewClient(): void {

    // continue only if android / if WebViewClient is undefined
    if (!isAndroid || WebViewClient) {
        return;
    }

    class WebViewClientSslImpl extends android.webkit.WebViewClient {

        constructor(public owner: any) {
            super();
            return global.__native(this);
        }

        public shouldOverrideUrlLoading(view: android.webkit.WebView, url: string) {
            return false;
        }

        public onPageStarted(view: android.webkit.WebView, url: string, favicon: android.graphics.Bitmap) {
            super.onPageStarted(view, url, favicon);
            const owner = this.owner;
            if (owner) {
                owner._onLoadStarted(url, undefined);
            }
        }

        public onPageFinished(view: android.webkit.WebView, url: string) {
            super.onPageFinished(view, url);
            const owner = this.owner;
            if (owner) {
                owner._onLoadFinished(url, undefined);
            }
        }

        public onReceivedError() {
            let view: android.webkit.WebView = arguments[0];

            if (arguments.length === 4) {
                let errorCode: number = arguments[1];
                let description: string = arguments[2];
                let failingUrl: string = arguments[3];

                super.onReceivedError(view, errorCode, description, failingUrl);

                const owner = this.owner;
                if (owner) {
                    owner._onLoadFinished(failingUrl, description + "(" + errorCode + ")");
                }
            } else {
                let request: any = arguments[1];
                let error: any = arguments[2];

                super.onReceivedError(view, request, error);
                const owner = this.owner;
                if (owner) {
                    owner._onLoadFinished(error.getUrl && error.getUrl(), error.getDescription() + "(" + error.getErrorCode() + ")");
                }
            }
        }

        public onReceivedSslError(view: any, handler: any, error: any) {
            handler.proceed();
        }
    };

    WebViewClient = WebViewClientSslImpl;
}

export function navigatingTo(args: EventData) {
    initializeWebViewClient();
    let page = <Page>args.object;
    page.bindingContext = new HelloWorldModel();
}

export function onWebViewLoaded(args: EventData) {
    let webView = <WebView>args.object;
    if (isAndroid) {
        const nativeView = webView.nativeView;
        const client = new WebViewClient(webView);
        nativeView.setWebViewClient(client);
        (<any>nativeView).client = client;
    }
    webView.src = "http://kalbar.kemenkumham.go.id";
}

In case if you run into typescript compilation errors, you may have to add tns-platform-declarations to your dev dependencies.

package.json

{
	"description": "NativeScript Application",
	"license": "SEE LICENSE IN <your-license-filename>",
	"readme": "NativeScript Application",
	"repository": "<fill-your-repository-here>",
	"nativescript": {
		"id": "com.demo.webview",
		"tns-android": {
			"version": "3.3.1"
		}
	},
	"dependencies": {
		"nativescript-theme-core": "~1.0.2",
		"tns-core-modules": "~3.3.0"
	},
	"devDependencies": {
		"babel-traverse": "6.26.0",
		"babel-types": "6.26.0",
		"babylon": "6.18.0",
		"lazy": "1.0.11",
		"nativescript-dev-typescript": "~0.5.0",
		"tns-platform-declarations": "3.3.0",
		"typescript": "~2.4.2"
	}
}

references.d.ts

/// <reference path="./node_modules/tns-core-modules/tns-core-modules.d.ts" />

/// <reference path="./node_modules/tns-platform-declarations/android.d.ts" />
/// <reference path="./node_modules/tns-platform-declarations/ios.d.ts" />

Extend NativeScript's default WebViewClient implementation
Using Wistia videos (Nativescript + Angular )
#5

Works for me in Android 7.0 :slight_smile:


#6

Thanks for advance but i use javascript. Typescript i got a little problem to translate it to javascript.


#7

i got it man. i change the file web-view.android.js and add this line

//overide
	WebViewClientImpl.prototype.onReceivedSslError = function (view, handler, error) {
		handler.proceed();
	}
//overide

before return WebViewClientImpl;

is it illegal to change node-modules directly??


#8

I would say it is not recommended, usually we don’t add node_modules to source control. Until you make sure it doesn’t get overwritten when you reinstall / update node modules, you should be good.


#9

i’m really thankful for your help. btw can i override or add new function to existing class like that???


#10

@shafrudin As I already said, it works if you add but I strongly don’t recommend that. It could be the last option you should go with.

If you copy the component inside app and customize then it will be easy for you while upgrading and it won’t break anything anytime.


#11

@manojdcoder how about showing how many progress data loaded? can you show me example of it??


#12

the code @manojdcoder

@shafrudin As I already said, it works if you add but I strongly don’t recommend that. It could be the last option you should go with.

If you copy the component inside app and customize then it will be easy for you while upgrading and it won’t break anything anytime.

could you show me how to do it in javascript. as your code is in typescript. thanks


#13

it wont work on tns release


#14

Working example demonstrating how to overwrite the default implementation of WebView can be found here: https://github.com/NickIliev/NS-Issues-2017/tree/master/stackoverflow/webViewClient/app


#15

@NickIliev has anything changed with your implementation this year? I used the example from your GitHub repo, but none of the overrides seem to be getting hit on android.