无法在 Android WebView 中设置 HttpURLConnection headers
Unable to set HttpURLConnection headers in Android WebView
我试图拦截 WebView 发送的每个请求并在执行请求之前修改 headers。有很多关于如何执行此操作的示例(Chrome 调试器中的 like this one), but I can't quite get it to work. Pages are able to load fine, but all of the requests look something like this;他们警告说我的 headers 的 "Provisional headers are shown" 和 none 存在。
这是我的代码的相关部分:
public class MyWebView extends WebView {
public MyWebView(Context context) {
super(context);
setWebViewClient(new MyWebViewClient());
}
private class MyWebViewClient extends WebViewClient {
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
WebResourceResponse response = null;
try {
URL url = new URL(request.getUrl().toString());
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod(request.getMethod());
conn.setRequestProperty("test-header", "test-value");
InputStream data;
if (conn.getResponseCode() / 100 == 2) {
data = conn.getInputStream();
}
else {
data = conn.getErrorStream();
}
response = new WebResourceResponse("text/html", "UTF-8", data);
}
catch (IOException e) {
}
return response;
}
}
}
我也尝试过使用 OkHttp,但得到了相同的结果。有人能让这个工作吗?
试试这个,而不是 shouldOverrideUrlLoading 而不是 shouldInterceptRequest
public class MyWebView extends WebView {
public MyWebView(Context context) {
super(context);
setWebViewClient(new MyWebViewClient());
}
private class MyWebViewClient extends WebViewClient {
@Override
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request)
{
final String url = request.getUrl().toString();
return getNewResponse(url);
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url)
{
return getNewResponse(url);
}
private WebResourceResponse getNewResponse(String url) {
final OkHttpClient httpClient = new OkHttpClient();
Response response = null;
try {
final Request request = new Request.Builder()
.url(url.trim())
.addHeader("test-header", "test-value")
.build();
response = httpClient.newCall(request).execute();
}
catch (Exception e) {
}
if (response == null) {
return null;
}
return new WebResourceResponse(
getMimeType(url),
response.header("content-encoding", "utf-8"),
response.body().byteStream()
);
}
private String getMimeType(String url) {
final String extension = MimeTypeMap.getFileExtensionFromUrl(url);
if (extension == null) {
return 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";
case "mp4":
return "video/mp4";
}
return MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
}
}
}
事实证明,我的代码实际上运行良好。问题似乎是 Chrome 网络检查器无法访问通过 HttpURLConnection(或 WebView 本身以外的任何内容)发送的请求的请求元数据,所以我的 headers 只是没有出现在那里。但是,使用 this tool 我迅速将所有请求 headers 显示为 json,我可以看到它们实际上是按预期交付的。
我试图拦截 WebView 发送的每个请求并在执行请求之前修改 headers。有很多关于如何执行此操作的示例(Chrome 调试器中的 like this one), but I can't quite get it to work. Pages are able to load fine, but all of the requests look something like this;他们警告说我的 headers 的 "Provisional headers are shown" 和 none 存在。
这是我的代码的相关部分:
public class MyWebView extends WebView {
public MyWebView(Context context) {
super(context);
setWebViewClient(new MyWebViewClient());
}
private class MyWebViewClient extends WebViewClient {
@Override
public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request) {
WebResourceResponse response = null;
try {
URL url = new URL(request.getUrl().toString());
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestMethod(request.getMethod());
conn.setRequestProperty("test-header", "test-value");
InputStream data;
if (conn.getResponseCode() / 100 == 2) {
data = conn.getInputStream();
}
else {
data = conn.getErrorStream();
}
response = new WebResourceResponse("text/html", "UTF-8", data);
}
catch (IOException e) {
}
return response;
}
}
}
我也尝试过使用 OkHttp,但得到了相同的结果。有人能让这个工作吗?
试试这个,而不是 shouldOverrideUrlLoading 而不是 shouldInterceptRequest
public class MyWebView extends WebView {
public MyWebView(Context context) {
super(context);
setWebViewClient(new MyWebViewClient());
}
private class MyWebViewClient extends WebViewClient {
@Override
@TargetApi(Build.VERSION_CODES.LOLLIPOP)
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request)
{
final String url = request.getUrl().toString();
return getNewResponse(url);
}
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url)
{
return getNewResponse(url);
}
private WebResourceResponse getNewResponse(String url) {
final OkHttpClient httpClient = new OkHttpClient();
Response response = null;
try {
final Request request = new Request.Builder()
.url(url.trim())
.addHeader("test-header", "test-value")
.build();
response = httpClient.newCall(request).execute();
}
catch (Exception e) {
}
if (response == null) {
return null;
}
return new WebResourceResponse(
getMimeType(url),
response.header("content-encoding", "utf-8"),
response.body().byteStream()
);
}
private String getMimeType(String url) {
final String extension = MimeTypeMap.getFileExtensionFromUrl(url);
if (extension == null) {
return 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";
case "mp4":
return "video/mp4";
}
return MimeTypeMap.getSingleton().getMimeTypeFromExtension(extension);
}
}
}
事实证明,我的代码实际上运行良好。问题似乎是 Chrome 网络检查器无法访问通过 HttpURLConnection(或 WebView 本身以外的任何内容)发送的请求的请求元数据,所以我的 headers 只是没有出现在那里。但是,使用 this tool 我迅速将所有请求 headers 显示为 json,我可以看到它们实际上是按预期交付的。