java Phonegap/Cordova 应用程序在 Jelly Bean 中中断 - Access-Control-Allow-Origin 和 setAllowUniversalAccessFromFileURLs

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12409440/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 08:46:55  来源:igfitidea点击:

Phonegap/Cordova App breaks in Jelly Bean - Access-Control-Allow-Origin and setAllowUniversalAccessFromFileURLs

javaandroidcordovaandroid-websettings

提问by mason81

I've been developing* with Cordova (aka Phonegap) for Android for well over a year now and am trying to make my apps available to run in Jelly Bean, but I am getting the following error:

一年多以来,我一直在使用 Android 的 Cordova(又名 Phonegap)进行开发*,并试图让我的应用程序可以在 Jelly Bean 中运行,但出现以下错误:

XMLHttpRequest cannot load http://127.0.0.1:40582/[somerandomstring]. Origin null is not allowed by Access-Control-Allow-Origin. at null:1

(and similar errors for any subsequent ajax requesting use of localhost or file://) Just to test, I grant access to everything in the config.xml in the section for Access-Control-Allow-Origin

(以及任何后续 ajax 请求使用 localhost 或 file:// 的类似错误)只是为了测试,我在 Access-Control-Allow-Origin 部分中授予对 config.xml 中所有内容的访问权限

<access origin="*"/>
<access origin="http://127.0.0.1*"/>

In my researchI have discovered the error is related to a setting change that Google made as of Android Jelly Bean. Here is what I found: From: https://git-wip-us.apache.org/repos/asf?p=incubator-cordova-android.git;a=commitdiff;h=07439ff9

在我的研究中,我发现该错误与 Google 对 Android Jelly Bean 所做的设置更改有关。这是我发现的:来自:https: //git-wip-us.apache.org/repos/asf?p=incubator-cordova-android.git;a=commitdiff;h=07439ff9

-- This is from org.apache.cordova.CordovaWebView

-- 这是来自 org.apache.cordova.CordovaWebView

// Jellybean rightfully tried to lock this down. Too bad they didn't give us a whitelist
// while we do this
if (android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1)
    Level16Apis.enableUniversalAccess(settings);

-- This is also from org.apache.cordova.CordovaWebView

-- 这也是来自 org.apache.cordova.CordovaWebView

// Wrapping these functions in their own class prevents warnings in adb like:
// VFY: unable to resolve virtual method 285: Landroid/webkit/WebSettings;.setAllowUniversalAccessFromFileURLs
@TargetApi(16)
private static class Level16Apis {
    static void enableUniversalAccess(WebSettings settings) {
         settings.setAllowUniversalAccessFromFileURLs(true);
     }
}

It's nice that Cordova tried to work around the change, but unfortunately this does not work...

很高兴 Cordova 尝试解决更改,但不幸的是这不起作用......

In these SO threads hereand hereI found a common solution, to simply change a setting as follows:

此处此处的这些 SO 线程中,我找到了一个通用解决方案,只需按如下方式更改设置:

if(android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
    super.appView.getSettings().setAllowUniversalAccessFromFileURLs(true);    
}

Now I get the following warning:

现在我收到以下警告:

Call requires API level 16 (current min is 8) 
android.webkit.WebSettings#setAllowUniversalAccessFromFileURLs

Here is what I have for the api in my AndroidManifest.xml

这是我在 AndroidManifest.xml 中的 api

<uses-sdk android:minSdkVersion="8" android:targetSdkVersion="16" />

Why is it requiring me to change the minSdkVersion to 16 rather than follow my targetSdkVersion which is 16?

为什么要求我将 minSdkVersion 更改为 16 而不是遵循我的 targetSdkVersion 为 16?

Thoughts?

想法?

Notes: I'm currently using Cordova 2.0, Eclipse Indigo SR2 (all updates current), Android SDK (all updates current), on Windows 7 Home (all updates current), Java 7 Update 7.

注意:我目前使用 Cordova 2.0、Eclipse Indigo SR2(所有更新当前)、Android SDK(所有更新当前)、Windows 7 Home(所有更新当前)、Java 7 Update 7。

回答by mason81

OK so after a ton of searching, guessing, and checking, I found a workable solution.

好的,经过大量的搜索、猜测和检查,我找到了一个可行的解决方案。

I had to create a separate function for the setAllowUniversalAccessFromFileURLs call... That fixed the TargetApi issue but then presented a different one on JellyBean where it wouldn't connect to the file I had in my loadURL call so I had to override the onReceivedError function. Here is my resulting code:

我不得不为 setAllowUniversalAccessFromFileURLs 调用创建一个单独的函数......这修复了 TargetApi 问题,但随后在 JellyBean 上呈现了一个不同的函数,它无法连接到我在 loadURL 调用中的文件,所以我不得不覆盖 onReceivedError 函数. 这是我的结果代码:

package com.MyUniqueDomain.MyUniquePackage;

import android.annotation.TargetApi;
import android.os.Bundle;
import org.apache.cordova.*;

public class MainActivity extends DroidGap {

    private int retryCount = 0;

    @Override
    public void onCreate(Bundle savedInstanceState) {

        super.onCreate(savedInstanceState);
        super.setStringProperty("loadingDialog", "Please wait -- loading...");
        super.init();
        if(android.os.Build.VERSION.SDK_INT > android.os.Build.VERSION_CODES.ICE_CREAM_SANDWICH_MR1) {
            fixJellyBeanIssues();
        }
        super.loadUrl("file:///android_asset/www/index.html");
    }

    @TargetApi(16)
    protected void fixJellyBeanIssues() {
        System.out.println(super.appView.toString());
        try {
            super.appView.getSettings().setAllowUniversalAccessFromFileURLs(true);
        } catch(NullPointerException e) {
            System.out.println(e.toString());
        }
    }

    // catch an error and if try again 1x or quit
    @Override
    public void onReceivedError( int errorCode, String description, String failingUrl)
    {
        if(retryCount < 3) {
            retryCount++;
            System.out.println("Connection failed, trying again. Retry Count: "+retryCount);
            super.loadUrl("file:///android_asset/www/index.html");
        } else {
            System.out.println("Sorry, it failed three times so I give up.");
            super.loadUrl("file:///android_asset/www/fail.html");
        }
        return;
    }
}