Android WebView“No'Access-Control-Allow-Origin'标头出现在请求的资源上”

时间:2016-06-23 07:27:53

标签: android webview

我正在尝试加载测试网页(在我的服务器中)。页面是:

<!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没有加载页面。甚至没有onProgressChanged在%40-50之后调用

此外,从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"
    />

4 个答案:

答案 0 :(得分:4)

您可以通过启用名为setAllowUniversalAccessFromFileURLs的WebSetting来解决此问题 这发生在Javascript层上 您可以在此处阅读相关内容:CORS

答案 1 :(得分:2)

你确定你不是在某个地方暂停计时器吗?因为在页面加载时调用mWebView.pauseTimers()会发生这种情况。

答案 2 :(得分:0)

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

但是有一种解决方法。

Using CORS - tutorial by 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:

Execute JavaScript in Android without WebView - tutorial by 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();
}

答案 3 :(得分:0)

从 Android 9(API 级别 28)开始,默认情况下禁用明文支持。
最好在您的服务器上安装安全证书。
仍然
为了避免在 Manifest

中添加以下行
<application
        ...
        android:label="@string/app_name"
        android:usesCleartextTraffic="true"
        ...

中提琴...