10

I'm trying to load a test web page (in my server). Page is:

<!DOCTYPE html>
<html>
<head>
    <title>Test</title>
</head>
<body>

<iframe width="420" height="315" src="http://www.youtube.com/embed/XGSy3_Czz8k?autoplay=1"/>

</body>
</html>

But webView is not loading page. Not even onProgressChanged called after %40-50

Also, this problem occurs all sites that loads js script from url. Including youtube, fb etc.

WebConsole: XMLHttpRequest cannot load https://googleads.g.doubleclick.net/pagead/id. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'https://www.youtube.com' is therefore not allowed access. 

Here my settings

    FrameLayout contentFrame = (FrameLayout) findViewById(R.id.ContentFrame);
    WebView mWebView = new WebView(this);

    mWebView.setWebChromeClient(new WebChromeClient());
    mWebView.setWebViewClient(new WebViewClient());
    mWebView.getSettings().setJavaScriptEnabled(true);
    mWebView.getSettings().setAllowUniversalAccessFromFileURLs(true);
    mWebView.getSettings().setAllowFileAccessFromFileURLs(true);

    mWebView.loadUrl("http://ozgur.dk/browser.html");

    contentFrame.removeAllViews();
    contentFrame.addView(mWebView);

Layout:

<?xml version="1.0" encoding="utf-8"?>
<FrameLayout
    android:id="@+id/ContentFrame"
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    />
1

4 Answers 4

4

You can solve this by enabling a WebSetting called setAllowUniversalAccessFromFileURLs
This is happening on the Javascript layer.
You can read up about it here : CORS

Sign up to request clarification or add additional context in comments.

Comments

3
+500

Are you sure you are not pausing timers in somewhere? Because this happens when you call mWebView.pauseTimers() when page loading.

1 Comment

Thanks so much, I wasn't aware that I'm pausing timer in other parts of activity.
0

You're trying to do a cross-domain request, which is impossible since it's on a different domain than your page is on.

There is however a workaround that.

Using CORS - tutorial by Monsur Hossain

An example using CORS (By Monsur Hossain):

function createCORSRequest(method, url) {
var xhr = new XMLHttpRequest();
if ("withCredentials" in xhr) {

// Check if the XMLHttpRequest object has a "withCredentials" property.
// "withCredentials" only exists on XMLHTTPRequest2 objects.
xhr.open(method, url, true);

} else if (typeof XDomainRequest != "undefined") {

// Otherwise, check if XDomainRequest.
// XDomainRequest only exists in IE, and is IE's way of making CORS requests.
xhr = new XDomainRequest();
xhr.open(method, url);

} else {

// Otherwise, CORS is not supported by the browser.
xhr = null;

}
return xhr;
}

var xhr = createCORSRequest('GET', url);
if (!xhr) {
throw new Error('CORS not supported');
} 

As a side note, if you want to run JavaScript on Android:

Execute JavaScript in Android without WebView - tutorial by Wesley Lin

An example using Rhino (by Wesley Lin):

Object[] params = new Object[] { "javaScriptParam" };

// Every Rhino VM begins with the enter()
// This Context is not Android's Context
Context rhino = Context.enter();

// Turn off optimization to make Rhino Android compatible
rhino.setOptimizationLevel(-1);
try {
Scriptable scope = rhino.initStandardObjects();

// Note the forth argument is 1, which means the JavaScript source has
// been compressed to only one line using something like YUI
rhino.evaluateString(scope, javaScriptCode, "JavaScript", 1, null);

// Get the functionName defined in JavaScriptCode
Object obj = scope.get(functionNameInJavaScriptCode, scope);

if (obj instanceof Function) {
    Function jsFunction = (Function) obj;

    // Call the function with params
    Object jsResult = jsFunction.call(rhino, scope, scope, params);
    // Parse the jsResult object to a String
    String result = Context.toString(jsResult);
}
} finally {
Context.exit();
}

Comments

-1

Starting with Android 9 (API level 28), cleartext support is disabled by default.
Better install security certificate on your server.
still
To circumvent add following line in Manifest

<application
        ...
        android:label="@string/app_name"
        android:usesCleartextTraffic="true"
        ...

viola...

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.