Je développe une application Android filtrant les demandes (avec une liste blanche) et utilisant une variable SSLSocketFactory
personnalisée. Pour cela, j'ai développé une WebViewClient
personnalisée et j'ai remplacé la méthode shouldInterceptRequest
. Je peux filtrer et utiliser ma SocketFactory
avec les demandes GET mais je ne peux pas intercepter les demandes POST.
Alors, y a-t-il un moyen d’intercepter les demandes POST dans une WebView
?
Voici le code de la méthode shouldInterceptRequest:
public final WebResourceResponse shouldInterceptRequest(WebView view, String urlStr) {
URI uri = URI.create(urlStr);
String scheme = uri.getScheme();
// If scheme not http(s), let the default webview manage it
if(!"http".equals(scheme) && !"https".equals(scheme)) {
return null;
}
URL url = uri.toURL();
if(doCancelRequest(url)) {
// Empty response
Log.d(TAG, "URL filtered: " + url);
return new WebResourceResponse("text/plain", "UTF-8", new EmptyInputStream());
} else {
Log.d(TAG, "URL: " + url);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setRequestProperty("User-Agent", mSettings.getUserAgentString());
// Configure connections
configureConnection(conn);
String mimeType = conn.getContentType();
String encoding = conn.getContentEncoding();
if(mimeType != null && mimeType.contains(CONTENT_TYPE_SPLIT)) {
String[] split = mimeType.split(CONTENT_TYPE_SPLIT);
mimeType = split[0];
Matcher matcher = CONTENT_TYPE_PATTERN.matcher(split[1]);
if(matcher.find()) {
encoding = matcher.group(1);
}
}
InputStream is = conn.getInputStream();
return new WebResourceResponse(mimeType, encoding, is);
}
}
Je faisais face au même problème il y a quelques jours.
J'ai donc construit une bibliothèque qui le résout:
https://github.com/KonstantinSchubert/request_data_webviewclient
Il s'agit d'un WebViewClient avec un WebResourceRequest personnalisé contenant la charge POST/PUT/... des demandes XMLHttpRequest.
Cela ne fonctionne cependant que pour ceux-ci - pas pour les formulaires et autres types de sources de demandes.
Le hack fonctionne, fondamentalement, en injectant un script dans le HTML qui intercepte les appels XMLHttpRequest. Il enregistre le contenu de l'article/put/... et l'envoie à un Android.webkit.JavascriptInterface
. Là, la demande est stockée jusqu'à ce que la méthode shouldInterceptRequest
soit appelée par Android ...
Utilisez GET au lieu de POST.
Problème connu: http://code.google.com/p/Android/issues/detail?id=9122
Nous avons également répondu ici: Android - Comment intercepter un formulaire POST dans Android WebViewClient sur API niveau 4
vous pouvez obtenir une valeur d'entrée avant de soumettre
https://github.com/henrychuangtw/WebView-Javascript-Inject
Étape 1: créer une classe appelée par javascript
class MyJavaScriptInterface
{
@JavascriptInterface
public void processHTML(String html)
{
//called by javascript
}
}
Étape 2: enregistrez une interface pour javascript
webview1.getSettings().setJavaScriptEnabled(true);
webview1.addJavascriptInterface(new MyJavaScriptInterface(), "MYOBJECT");
Étape 3: injecter du javascript à la page
webview1.setWebViewClient(new WebViewClient() {
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
StringBuilder sb = new StringBuilder();
sb.append("document.getElementsByTagName('form')[0].onsubmit = function () {");
sb.append("var objPWD, objAccount;var str = '';");
sb.append("var inputs = document.getElementsByTagName('input');");
sb.append("for (var i = 0; i < inputs.length; i++) {");
sb.append("if (inputs[i].type.toLowerCase() === 'password') {objPWD = inputs[i];}");
sb.append("else if (inputs[i].name.toLowerCase() === 'email') {objAccount = inputs[i];}");
sb.append("}");
sb.append("if (objAccount != null) {str += objAccount.value;}");
sb.append("if (objPWD != null) { str += ' , ' + objPWD.value;}");
sb.append("window.MYOBJECT.processHTML(str);");
sb.append("return true;");
sb.append("};");
view.loadUrl("javascript:" + sb.toString());
}
});
J'ai une de mes réponses sur le fil ci-dessus http://code.google.com/p/Android/issues/detail?id=9122
S'il vous plaît voir commentaire # 31
Certaines des mises en garde de ma solution sont les suivantes:
En dehors de cela, j'ai trouvé ce github repo qui semble résoudre ce problème d'une autre manière hacky. J'ai examiné le code mais je n'ai pas eu le temps de le mettre en œuvre et de le tester. Mais ça vaut le coup d'essayer.