Android WebView“请求的资源上没有'Access-Control-Allow-Origin'标题”

9

我正在尝试加载一个测试网页(在我的服务器上)。该页面为:

<!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>

但是webView无法加载页面。甚至在%40-50之后也没有调用onProgressChanged。

此外,这个问题发生在所有从url加载js脚本的网站上。包括youtube、fb等。

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. 

这里是我的设置

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

布局:

<?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"
    />

请参考类似的问题:https://dev59.com/H2Ij5IYBdhLWcg3wpmoH 和 https://dev59.com/0GIj5IYBdhLWcg3wRjOr - user861594
4个回答

4

3
你确定你没有在某个地方暂停计时器吗?因为当页面加载时调用 mWebView.pauseTimers(),就会出现这种情况。

1
非常感谢,我没有意识到我在活动的其他部分暂停了计时器。 - Lazy

0

您正在尝试进行跨域请求,但这是不可能的,因为它在与您的页面不同的域上。

然而,有一个解决方法。

使用CORS - Monsur Hossain的教程

以下是使用CORS的示例(由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');
} 

作为一个旁注,如果你想在Android上运行JavaScript:

在Android上执行JavaScript而不使用WebView - Wesley Lin的教程

一个使用Rhino的例子(由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();
}

-1

从Android 9(API级别28)开始,默认情况下禁用明文支持。
最好在您的服务器上安装安全证书。
但是
为了规避此问题,请在清单中添加以下行

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

维奥拉...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接