【问题标题】:Android Webview: disable CORSAndroid Webview:禁用 CORS
【发布时间】:2013-06-20 18:58:49
【问题描述】:

Android 是否允许原生应用为 http://(不是本地/文件)请求禁用 CORS 安全策略?

在我的本机应用程序中,webview 通过 http:// 显示远程 html,而不是在本地/文件系统上。这似乎与 Web 浏览器一样受到 CORS 限制。

Worakround:一个用于 ajax 跨域请求的 native-js 桥接器,它没有 Access-Control-Allow-Origin: * 是我的快速解决方案。 (jsonp 或服务器端代理不是一个选项,因为客户端的 cookie+ip 由 web 服务检查。)

可以为应用内网页视图禁用此政策吗?

如果有一个简单的标志允许 js 绕过这个限制“本机”应用程序的 webview 的限制,请告诉我。

【问题讨论】:

    标签: android webview cors


    【解决方案1】:

    这现在可以从 Android API 级别 21 开始。您可以像这样创建一个 OPTIONS 响应:

    public class OptionsAllowResponse {
        static final SimpleDateFormat formatter = new SimpleDateFormat("E, dd MMM yyyy kk:mm:ss", Locale.US);
    
        @TargetApi(21)
        static WebResourceResponse build() {
            Date date = new Date();
            final String dateString = formatter.format(date);
    
            Map<String, String> headers = new HashMap<String, String>() {{
                put("Connection", "close");
                put("Content-Type", "text/plain");
                put("Date", dateString + " GMT");
                put("Access-Control-Allow-Origin", /* your domain here */);
                put("Access-Control-Allow-Methods", "GET, POST, DELETE, PUT, OPTIONS");
                put("Access-Control-Max-Age", "600");
                put("Access-Control-Allow-Credentials", "true");
                put("Access-Control-Allow-Headers", "accept, authorization, Content-Type");
                put("Via", "1.1 vegur");
            }};
    
            return new WebResourceResponse("text/plain", "UTF-8", 200, "OK", headers, null);
        }
    }
    

    然后从您的 WebViewClient 实现中调用它,如下所示:

        @Override
        @TargetApi(21)
        public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
            if (request.getMethod().equalsIgnoreCase("OPTIONS")) {
                return OptionsAllowResponse.build();
            }
    
            return null;
        }
    

    这仅适用于 API 级别 21,因为 OPTIONS 响应需要检查来自 WebResourceRequest 的请求的 HTTP 方法,该方法仅在 API 21 之后可用。

    【讨论】:

    • 我看不出这如何禁用 CORS,它只是拦截请求并返回您想要的内容,而不是实际的请求数据。
    • 你说得对,它不直接处理GET/PUT/POST请求的请求数据,但是CORS涉及两个请求:第一个是HTTP OPTIONS 请求没有请求数据,检查 GET/PUT/POST 是否可以通过,如果可以,WebView 将继续使用数据发出实际请求。此代码覆盖第一个 OPTIONS 请求的响应,以便第二个请求通过。
    • 如何从 javascript 发出请求?在我的测试中,我从来没有收到过 OPTIONS 请求,只是实际请求失败了,所以我结束了使用HttpURLConnection 来获取文件数据并将其返回到WebResourceResponse
    • 在 Javascript 中,您只需像往常一样发出请求,例如。通过 XMLHttpRequest 或 fetch 或其他方式。这里的 Java 在 WebViewClient 类中实现,该类分配给运行 Javascript 的 WebView。我不确定您的设置是什么或您遇到了 CORS 问题,但您应该阅读 developer.mozilla.org/en-US/docs/Web/HTTP/CORS 以了解 CORS 协议。
    • @davidgoli 当我使用 POST 请求时,知道如何克服这个 frm REACT-NATIVE 吗?请看stackoverflow.com/questions/52178543/…
    【解决方案2】:

    AFAIK 这是不可能的,相信我,我已经尝试了很多方法。

    你能做的最好的就是覆盖资源加载。见Intercept and override HTTP-requests from WebView

    【讨论】:

    • 抱歉再次询问。从 API 11 开始,shouldInterceptRequest 无法通过将标头响应操作为始终接受 CORS 来“修复”这个问题?
    • 可能的,请看下面我的回答。
    • @MarcoMartinelli 当我使用 POST 请求时,知道如何克服这个 frm REACT-NATIVE 吗?请看stackoverflow.com/questions/52178543/…
    【解决方案3】:

    帮助我在 Xamarin 中使用 c# 的较短版本如下:

        public override WebResourceResponse ShouldInterceptRequest(WebView view, IWebResourceRequest request)
        {
            if (request.Url.SchemeSpecificPart.StartsWith("//<domain>/"))
            {
                request.RequestHeaders.Add("Access-Control-Allow-Origin", "*");
            }
    
            return base.ShouldInterceptRequest(view, request);
        }
    

    此覆盖是针对 Android.Webkit.WebViewClient 完成的,其中 &lt;domain&gt; 是被 CORS 策略阻止的那个。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-04-30
      • 2011-10-26
      • 2017-12-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多