Android Webview: disable CORS

2019-01-17 22:54发布

问题:

Does Android allow native apps to disable CORS security policies for http:// (not local/file) requests?

In my native app, a webview shows a remote html via http://, not on the local/file system. This seems to be CORS-restricted in the same way as within webbrowsers.

Worakround: A native-js bridge for ajax requests to cross-domains which do not have Access-Control-Allow-Origin: * is my quick'n'dirt solution. (jsonp or server-side proxy is not an option because cookie+ip of client are checked by the webservice.)

Can this policy be disabled for inapp webviews?

Please let me know, if there is a simple flag for allowing js to bypass this restriction which limits the "native" app's webview.

回答1:

AFAIK this is not possible, and believe me, I've tried many ways.

The best you can do is override resource loading. See Intercept and override HTTP-requests from WebView



回答2:

This is now possible as of Android API level 21. You can create an OPTIONS response like so:

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

and then call it from your WebViewClient implementation as follows:

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

        return null;
    }

This only works from API level 21, since the OPTIONS response requires inspecting the requested HTTP method from the WebResourceRequest, which is only available since API 21.