【问题标题】:Android WebView "No 'Access-Control-Allow-Origin' header is present on the requested resource"Android WebView“请求的资源上不存在'Access-Control-Allow-Origin'标头”
【发布时间】:2016-10-25 09:22:57
【问题描述】:

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

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

【问题讨论】:

标签: android webview


【解决方案1】:

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

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

中提琴...

【讨论】:

    【解决方案2】:

    您确定您没有在某处暂停计时器吗?因为当您在页面加载时调用mWebView.pauseTimers() 时会发生这种情况。

    【讨论】:

    • 非常感谢,我不知道我正在暂停其他活动部分的计时器。
    【解决方案3】:

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

    不过有一种解决方法。

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

    【讨论】:

      【解决方案4】:

      您可以通过启用名为 setAllowUniversalAccessFromFileURLs 的 WebSetting 来解决此问题
      这发生在 Javascript 层。
      你可以在这里阅读:CORS

      【讨论】:

        猜你喜欢
        • 2013-11-29
        • 2014-07-28
        • 2014-01-19
        • 2013-12-07
        相关资源
        最近更新 更多