Android - 如何在 API 级别 4 的 android WebViewClient 中拦截表单 POST
Posted
技术标签:
【中文标题】Android - 如何在 API 级别 4 的 android WebViewClient 中拦截表单 POST【英文标题】:Android - how to intercept a form POST in android WebViewClient on API level 4 【发布时间】:2011-04-09 12:44:12 【问题描述】:我有一个WebViewClient
附加到我的WebView
,如下所示:
webView.setWebViewClient(new MyWebViewClient());
这是我对MyWebViewClient
的实现:
private class MyWebViewClient extends WebViewClient
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url)
webView.loadUrl(url);
return true;
我给WebView
一个URL 以通过loadUrl()
加载。如果页面中有链接(a href...
),我的shouldOverrideUrlLoading
方法被调用,我可以拦截链接点击。
但是,如果我有一个方法为POST
的表单,则不会调用shouldOverrideUrlLoading
方法。
我在这里注意到一个类似的问题:http://code.google.com/p/android/issues/detail?id=9122 这似乎建议在我的WebView
中覆盖postUrl
。但是,此 API 仅从 API 级别 5 开始可用。
如果我处于 API 级别 4,我该怎么办?有没有其他方法可以拦截表单帖子?
【问题讨论】:
您可以尝试在 WebViewClient 中覆盖 onPageStarted 回调。 谢谢。我试过了,它工作正常,但问题是我不想加载表单的页面 - 这是一个虚假的 URL,所以我最终得到了 webview 错误页面。如果 URL 与我的表单 URL 匹配,我通过检查 onPageStarted 来解决此问题,如果是,则在我的应用程序中处理此问题,然后告诉 webViewClient 返回。这听起来合理吗? 您找到解决方案了吗? 这些天,我们有WebResourceResponse shouldInterceptRequest(WebView view, WebResourceRequest request)
可以拦截 POST。它仍然不够完美。您不能简单地设置自定义标头并让请求继续 - 您必须 handle it all yourslef
【参考方案1】:
您真的需要使用 POST 吗?如果您想在本地处理表单数据,为什么不让一段 javascript 使用 addJavascriptInterface 处理您的表单并与“本机”java 代码接口。例如
WebView engine = (WebView) findViewById(R.id.web_engine);
engine.getSettings().setJavaScriptEnabled(true);
engine.addJavascriptInterface(new MyBridge(this), "bridge");
engine.loadUrl(...)
你的桥基本上可以是任何类,你应该能够直接从 javascript 访问它的方法。例如
public class MyBridge
public MyBridge(Context context)
// ...
public String doIt(String a, String b)
JSONArray result = new JSONArray();
result.put("Hello " + a);
result.put("Hello " + b);
return result.toString();
您的 html / javascript 可能如下所示:
<script type="text/javascript">
$("#button").click(function()
var a = $("#a").val();
var b = $("#b").val();
var result=JSON.parse(bridge.doIt(a, b));
// ...
</script>
<input id="a"><input id="b"><button id="button">click</button>
【讨论】:
这是理想的解决方案,但不幸的是似乎不适用于 2.3 模拟器和那一代的各种手机。查找 VM 崩溃并出现以下错误:JNI WARNING: jarray 0x40533560 points to non-array object (Ljava/lang/String;) Google for that for more information【参考方案2】:这是一个已知问题,shouldOverrideUrlLoading
不会捕获 POST。有关详细信息,请参阅http://code.google.com/p/android/issues/detail?id=9122。
使用 GET!我个人尝试使用 POST,因为我预计 GET 参数会受到一些限制(即 URL 的长度),但我只是在本地通过 GET 成功传递了 32000 个字节,没有任何问题。
【讨论】:
我真的需要找到解决方案。因为,就我而言,实际上切换到 GET 不在我的手中。我无法理解它是如何在 android 中丢失的。原因是什么。 在webView
中覆盖postUrl
。这从 API 级别 5 开始可用。
我做了,没有成功。不处理。
我也需要一个解决方案。我需要为通过我的 WebView 发出的所有请求添加一个自定义标头。我首先加载了一个重定向(通过 POST wheee!)到另一个页面的 url,但我无法捕获该重定向并正确添加自定义标题。我无法控制服务器以及它使用 POST 而不是 GET 的事实。【参考方案3】:
我认为您可以从 WebViewClient
覆盖 onLoadResource(WebView view, String url)
。该功能在 API LEVEL 1 中添加。
当WebView
将加载给定 url 指定的资源时调用此函数。资源包括js
、css
、iframe
嵌入网址。代码示例如下:
@Override
public void onLoadResource(WebView view, String url)
if (url.indexOf("http://www.example.com") != -1 && view != null)
// open url in default browser
view.stopLoading();
view.getContext().startActivity(new Intent(Intent.ACTION_VIEW, Uri.parse(url)));
【讨论】:
在问题中要求拦截 POST 请求而不尝试加载资源。两者都不一样。 对于那些对此响应添加缺点的人:根据HTTP标准,“资源”不仅仅是文件(js,css等)。 “资源”是 URI 指向的任何东西。例如,API 端点也是资源。以上是关于Android - 如何在 API 级别 4 的 android WebViewClient 中拦截表单 POST的主要内容,如果未能解决你的问题,请参考以下文章
Google ADs(ADmobs) 需要 API 级别 4.0 Android