【问题标题】:Adding custom header to WebView by adding headers to WebResourceRequest's headers in shouldInterceptRequest doesn't work通过在 shouldInterceptRequest 中向 WebResourceRequest 的标头添加标头向 WebView 添加自定义标头不起作用
【发布时间】:2016-07-16 16:04:08
【问题描述】:

我需要在 WebView 中加载的页面添加自定义标题,但它不起作用,标题未设置:

@Override
public WebResourceResponse shouldInterceptRequest (WebView view,  WebResourceRequest request)
{
    request.getRequestHeaders().add("MyHeader","MyValue"); 
    return super.shouldInterceptRequest(view, request);
}

我在这里做错了什么?我在 Android 5 上运行。

我在 SO 上看到了很多答案,说您必须自己执行 HTTP 请求并返回 WebResourceResponse。这是因为即使您像我一样修改标题,它们也会被忽略?

我还试图在 Android 源代码中找到调用的位置 调用 shouldInterceptRequest 的位置在哪里,所以我可以自己查看它是如何工作的,但我找不到。

【问题讨论】:

  • 你的 minSdkVersion 是否设置为 21,因为 shouldInterceptRequest (WebView view, WebResourceRequest request) 仅从版本 21 开始支持
  • 是的。它应该工作吗?

标签: android android-webview


【解决方案1】:

我自己找到了答案,就在docs

如果返回值为null,WebView会继续加载 资源照常。否则,返回响应和数据将是 用过。

此外,一个简单的测试显示WebViewClient.shouldInterceptRequest 的基本实现返回null。所以 WebView 基本上还是照常加载资源。

换句话说,我不能只是向标题添加一个值并期望它被使用。 我实际上需要自己做请求并返回响应。

太糟糕了,没有办法只修改标题并让默认实现使用它。

我知道我可以通过调用带有标题的loadUrl 方法来设置标题,但是如果我先加载本地页面然后加载在线页面,则不会使用标题。

【讨论】:

  • 我不希望您的第一种方法起作用,因为您只是检索一组标题,并向该组添加另一个项目。您实际上并没有将新集分配给请求。棘手的部分是分配新的标头集,因为 WebResourceRequest 中没有 setHeaders 方法
  • @Chicowitz getRequestHeaders() 返回一个 HashMap 实例,它是请求内部的同一个实例,而不是副本。该请求引用了相同的实例。这意味着如果您向其添加值,则附加值已经在请求中。您不需要分配“新集”,没有新集,它是相同的集。所以这不是它不起作用的原因。你只是在混淆问题。 Don Box 已经明确说明了为什么它在这个答案中不起作用。
  • @Don Box 您是否找到任何其他解决方法?
【解决方案2】:

WebViewClient 中提供的shouldInterceptRequest 的默认方法实现返回 null,因此如果我们需要设置额外的标头,则必须创建 WebResourceResponse 并返回它。

https://android.googlesource.com/platform/frameworks/base.git/+/master/core/java/android/webkit/WebViewClient.java

【讨论】:

    【解决方案3】:

    我能够在我的一个 shouldInterceptRequest 处理程序中使用此代码向 response 添加自定义标头:

    InputStream is = new ByteArrayInputStream(result.getBytes());
    WebResourceResponse resp = new WebResourceResponse("text/html", null, is);
    Map<String, String> hdrs = resp.getResponseHeaders();
    Map<String, String> newHdrs = new HashMap<>();
    if(hdrs != null) newHdrs.putAll(hdrs);
    newHdrs.put("Access-Control-Allow-Origin", "*");
    resp.setResponseHeaders(newHdrs);
    return resp;
    

    请注意,这是原帖发布 5 年后,我正在编写 API 30

    【讨论】:

    • 这里的结果是什么?是httpresult吗?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-09-12
    • 2019-02-19
    • 2012-11-15
    • 1970-01-01
    • 1970-01-01
    • 2011-02-04
    • 2021-03-09
    相关资源
    最近更新 更多