向WebView资源请求添加自定义标头 - android

时间:2011-09-30 13:06:01

标签: java android webkit android-webview

我需要为来自WebView的每个请求添加自定义标头。我知道loadURL具有extraHeaders的参数,但这些参数仅适用于初始请求。所有后续请求都不包含标头。我查看了WebViewClient中的所有覆盖,但没有任何内容允许向资源请求添加标头 - onLoadResource(WebView view, String url)。任何帮助都会很棒。

谢谢, 雷

12 个答案:

答案 0 :(得分:66)

尝试

loadUrl(String url, Map<String, String> extraHeaders)

要将资源添加到资源加载请求,请自定义WebViewClient并覆盖:

API 24+:
WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request)
or
WebResourceResponse shouldInterceptRequest(WebView view, String url)

答案 1 :(得分:29)

您需要使用WebViewClient.shouldInterceptRequest

拦截每个请求

每次拦截时,您需要获取网址,自己发出此请求,然后返回内容流:

div.all {
    position: relative;
}

如果您的最低API目标是21级,则可以使用新的shouldInterceptRequest,它会为您提供其他请求信息(例如标题),而不仅仅是网址。

答案 2 :(得分:19)

也许我的回复很晚,但它涵盖API 低于高于 21级。

要添加标题,我们应该拦截每个请求使用所需的标题创建新的

因此我们需要覆盖两种情况下调用的 shouldInterceptRequest 方法: 1.对于API直到21级; 2.对于API级别21 +

    webView.setWebViewClient(new WebViewClient() {

        // Handle API until level 21
        @SuppressWarnings("deprecation")
        @Override
        public WebResourceResponse shouldInterceptRequest(WebView view, String url) {

            return getNewResponse(url);
        }

        // Handle API 21+
        @TargetApi(Build.VERSION_CODES.LOLLIPOP)
        @Override
        public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {

            String url = request.getUrl().toString();

            return getNewResponse(url);
        }

        private WebResourceResponse getNewResponse(String url) {

            try {
                OkHttpClient httpClient = new OkHttpClient();

                Request request = new Request.Builder()
                        .url(url.trim())
                        .addHeader("Authorization", "YOU_AUTH_KEY") // Example header
                        .addHeader("api-key", "YOUR_API_KEY") // Example header
                        .build();

                Response response = httpClient.newCall(request).execute();

                return new WebResourceResponse(
                        null,
                        response.header("content-encoding", "utf-8"),
                        response.body().byteStream()
                );

            } catch (Exception e) {
                return null;
            }

        }
   });

如果应该处理响应类型,您可以更改

        return new WebResourceResponse(
                null, // <- Change here
                response.header("content-encoding", "utf-8"),
                response.body().byteStream()
        );

        return new WebResourceResponse(
                getMimeType(url), // <- Change here
                response.header("content-encoding", "utf-8"),
                response.body().byteStream()
        );

并添加方法

        private String getMimeType(String url) {
            String type = null;
            String extension = MimeTypeMap.getFileExtensionFromUrl(url);

            if (extension != null) {

                switch (extension) {
                    case "js":
                        return "text/javascript";
                    case "woff":
                        return "application/font-woff";
                    case "woff2":
                        return "application/font-woff2";
                    case "ttf":
                        return "application/x-font-ttf";
                    case "eot":
                        return "application/vnd.ms-fontobject";
                    case "svg":
                        return "image/svg+xml";
                }

                type = MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
            }

            return type;
        }

答案 3 :(得分:18)

如前所述,您可以这样做:

 WebView  host = (WebView)this.findViewById(R.id.webView);
 String url = "<yoururladdress>";

 Map <String, String> extraHeaders = new HashMap<String, String>();
 extraHeaders.put("Authorization","Bearer"); 
 host.loadUrl(url,extraHeaders);

我测试了这个并且使用MVC控制器,我扩展了Authorize Attribute以检查标头,标头就在那里。

答案 4 :(得分:7)

这对我有用:

  1. 首先你需要创建方法,它将返回你的方法 要添加到请求的标头:

    private Map<String, String> getCustomHeaders()
    {
        Map<String, String> headers = new HashMap<>();
        headers.put("YOURHEADER", "VALUE");
        return headers;
    }
    
  2. 其次,您需要创建WebViewClient:

    private WebViewClient getWebViewClient()
    {
    
        return new WebViewClient()
        {
    
        @Override
        @TargetApi(Build.VERSION_CODES.LOLLIPOP)
        public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request)
        {
            view.loadUrl(request.getUrl().toString(), getCustomHeaders());
            return true;
        }
    
        @Override
        public boolean shouldOverrideUrlLoading(WebView view, String url)
        {
            view.loadUrl(url, getCustomHeaders());
            return true;
        }
    };
    }
    
  3. 将WebViewClient添加到WebView:

    webView.setWebViewClient(getWebViewClient());
    
  4. 希望这有帮助。

答案 5 :(得分:4)

您应该能够通过跳过loadUrl并使用Java的HttpURLConnection编写自己的loadPage来控制所有标头。然后使用webview的loadData显示响应。

无权访问Google提供的标头。它们位于WebView源代码深处的JNI调用中。

答案 6 :(得分:1)

这对我有用。像下面这样创建WebViewClient并将webclient设置为webview。我不得不使用webview.loadDataWithBaseURL作为我的网址(在我的内容中)没有baseurl但只有相对网址。只有在使用loadDataWithBaseURL设置了baseurl时,才能正确获取url。

public WebViewClient getWebViewClientWithCustomHeader(){
    return new WebViewClient() {
        @Override
        public WebResourceResponse shouldInterceptRequest(WebView view, String url) {
            try {
                OkHttpClient httpClient = new OkHttpClient();
                com.squareup.okhttp.Request request = new com.squareup.okhttp.Request.Builder()
                        .url(url.trim())
                        .addHeader("<your-custom-header-name>", "<your-custom-header-value>")
                        .build();
                com.squareup.okhttp.Response response = httpClient.newCall(request).execute();

                return new WebResourceResponse(
                        response.header("content-type", response.body().contentType().type()), // You can set something other as default content-type
                        response.header("content-encoding", "utf-8"),  // Again, you can set another encoding as default
                        response.body().byteStream()
                );
            } catch (ClientProtocolException e) {
                //return null to tell WebView we failed to fetch it WebView should try again.
                return null;
            } catch (IOException e) {
                //return null to tell WebView we failed to fetch it WebView should try again.
                return null;
            }
        }
    };

}

答案 7 :(得分:0)

我遇到了同样的问题并解决了。

如前所述,您需要创建自定义WebViewClient并覆盖shouldInterceptRequest方法。

WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request)

该方法应该在返回&#34;空&#34;时发出webView.loadUrl。 WebResourceResponse。

这样的事情:

@Override
public boolean shouldInterceptRequest(WebView view, WebResourceRequest request) {

    // Check for "recursive request" (are yor header set?)
    if (request.getRequestHeaders().containsKey("Your Header"))
        return null;

    // Add here your headers (could be good to import original request header here!!!)
    Map<String, String> customHeaders = new HashMap<String, String>();
    customHeaders.put("Your Header","Your Header Value");
    view.loadUrl(url, customHeaders);

    return new WebResourceResponse("", "", null);
}

答案 8 :(得分:0)

这是使用HttpUrlConnection的实现:

download

请注意,这不适用于POST请求,因为WebResourceRequest不提供POST数据。有fetch,它使用JavaScript注入方法来拦截POST数据。

答案 9 :(得分:-2)

您可以使用:

@Override

 public boolean shouldOverrideUrlLoading(WebView view, String url) {

                // Here put your code
                Map<String, String> map = new HashMap<String, String>();
                map.put("Content-Type","application/json");
                view.loadUrl(url, map);
                return false;

            }

答案 10 :(得分:-4)

Page:MainActivity.java

导入android.webkit.WebView;

公共类MainActivity扩展了AppCompatActivity {

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

    WebView WebViw = (WebView) findViewById(R.id.webView1);
    WebViw.getSettings().setJavaScriptEnabled(true);
    WebViw.getSettings().setUserAgentString("User-Agent");
    WebViw.loadUrl("http://www.educationlife-online.com/");

}

}

这就是成功。

答案 11 :(得分:-9)

使用此:

webView.getSettings().setUserAgentString("User-Agent");