[JAVA] Dinge, die Sie beim Abfangen einer Anfrage mit Android WebView vergessen sollten # shouldInterceptRequest

Wenn Sie die HTTP-Antwortbehandlung und das Zeitlimit unabhängig voneinander in Android WebView implementieren möchten, können Sie shouldInterceptRequest überschreiben und die HTTP-Kommunikation unabhängig voneinander implementieren.

Da es sich um ein Beispiel handelt, handelt es sich um eine grobe Implementierung. Nehmen wir jedoch an, Sie haben es wie folgt implementiert.

override fun shouldInterceptRequest(view: WebView?, request: WebResourceRequest?): WebResourceResponse? {
    val latch = CountDownLatch(1)
    var res: InputStream? = null

    val call = createOkHttpClient().newCall(Request.Builder().url(request?.url.toString()).method("POST", RequestBody.create(null, "hoge")).build())
    call.enqueue(object: Callback {
        override fun onFailure(call: Call, e: IOException) {
            latch.countDown()
        }

        override fun onResponse(call: Call, response: Response) {
            res = response.body()?.byteStream()
            latch.countDown()
        }
    })

    latch.await()
    return WebResourceResponse("text/html", "UTF-8",res)
}

private val cookieStore = HashMap<String, MutableList<Cookie>>()

fun createOkHttpClient(): OkHttpClient {
    return OkHttpClient.Builder()
        .cookieJar(object: CookieJar {
            override fun saveFromResponse(url: HttpUrl, cookies: MutableList<Cookie>) {
                cookieStore[url.host()] = cookies
        }

            override fun loadForRequest(url: HttpUrl): MutableList<Cookie> {
                val cookies = cookieStore[url.host()]
                return cookies ?: ArrayList()
            }
        })
        .build()
}

Aber seien Sie vorsichtig, wenn Sie dies verwenden. Betrachten Sie beispielsweise den Fall, dass Sie den folgenden HTML-Code erhalten.

<html>                                                                                                                                                                                                                                        
<body>
<script type="text/javascript">
  function doPost() {
    document.TestForm.submit();
  }
</script>

<h1>Test</h1>

<form id="TestForm" name="TestForm" action="http://192.168.100.2:3000/hoge" method="post">
  <input type="hidden" name="hoge" value="hogeVal"/>
  <input type="hidden" name="fuga" value="fugaVal"/>
  <input type="submit" value="submit">
</form>
<script type="text/javascript">
  doPost();
</script>
</body>
</html>

Da WebView über eine HTML-Analysefunktion verfügt, wird die Funktion doPost beim Lesen des obigen HTML-Codes aufgerufen und für das im Tag

definierte `` `http: //192.168.100.2: 3000 / hoge```. Und senden Sie die Anfrage automatisch.

Wenn WebView zu diesem Zeitpunkt für das Laden von Ressourcen mit shouldInterceptRequest verantwortlich ist (es sei denn, es überschreibt shouldInterceptRequest), Der Wert des versteckten Attributs des Tags \ <input > wird automatisch POSTED. Wenn der Entwickler die Anforderung jedoch mithilfe von OkHTTP usw. selbst implementiert, muss er den HTML-Inhalt analysieren und selbst hinzufügen. nicht. (Standardmäßig wird der Wert des ausgeblendeten Attributs nicht zugewiesen.)

Lassen Sie uns den folgenden Server einrichten und das Protokoll betrachten.

{-# LANGUAGE OverloadedStrings #-}                                                                                                                                                                                                            
module Main where

import Web.Scotty
import Control.Monad.IO.Class (liftIO)

main :: IO ()
main = scotty 3000 $ do
  post "/test.html" $ file "./static/test.html" >> setHeader "Content-Type" "text/html"
  post "/hoge" $ do
    (liftIO . putStrLn $ ("Access to /hoge. Headers: " :: String)) >> headers >>= liftIO . print
    (liftIO . putStrLn $ ("Params: " :: String)) >> params >>= liftIO . print
    text "hoge success"

Wenn Sie nicht überschreiben, sollteInterceptRequest


Access to /hoge. Headers: 
[("Host","192.168.100.151:3000"),("Connection","keep-alive"),("Content-Length","25"),("Cache-Control","max-age=0"),("Origin","http://192.168.100.151:3000"),("Upgrade-Insecure-Requests","1"),("Content-Type","application/x-www-form-urlencoded"),("User-Agent","Mozilla/5.0 (Linux; Android 9; Android SDK built for x86 Build/PSR1.180720.012; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/66.0.3359.158 Mobile Safari/537.36"),("Accept","text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8"),("Referer","http://192.168.100.151:3000/test.html"),("Accept-Encoding","gzip, deflate"),("Accept-Language","ja-JP,en-US;q=0.9"),("X-Requested-With","com.badlogic.masaki.webviewjsinterfacesample")]
Params: 
[("hoge","hogeVal"),("fuga","fugaVal")]

Wann sollteIntercept in der obigen Implementierung überschrieben werden?


Access to /hoge. Headers: 
[("Content-Length","4"),("Host","192.168.100.151:3000"),("Connection","Keep-Alive"),("Accept-Encoding","gzip"),("User-Agent","okhttp/3.10.0")]
Params: 
[]

Der im versteckten HTML-Attribut definierte Inhalt wird nicht veröffentlicht. In diesem Fall wird die beabsichtigte Antwort nicht vom Server zurückgegeben. Darüber hinaus werden auch Header-Informationen wie User-Agent ersetzt. Seien Sie daher vorsichtig, wenn Sie shouldInterceptRequest überschreiben.

HTML-Analyse ist erforderlich, um den Wert des versteckten Attributs zu POSTEN. Hier gibt es bereits verschiedene Informationen.

Wie Sie den Inhalt von HTML erhalten, war wie folgt hilfreich. https://stackoverflow.com/questions/8200945/how-to-get-html-content-from-a-webview

So legen Sie den POST-Parameter von application / x-www-form-urlencoded mit OkHttp fest Es war hilfreich. https://stackoverflow.com/questions/35756264/how-do-i-post-data-using-okhttp-library-with-content-type-x-www-form-urlencoded

Ich habe dasselbe in Vorheriger Artikel gesagt, aber da der Zweck von WebView darin besteht, HTML zu rendern, ist es nicht so, als würde man es für WebAPI-Aufrufe verwenden. ..

Recommended Posts

Dinge, die Sie beim Abfangen einer Anfrage mit Android WebView vergessen sollten # shouldInterceptRequest
Dinge, auf die Sie beim Erstellen eines Frameworks achten sollten
Dinge, über die Sie nachdenken sollten, wenn Sie sich für die Architektur eines neuen Systems entscheiden
Dinge, die beim Ausführen eines bestimmten Jobs mit Spring Batch zu beachten sind
Senden Sie eine Pull-Anfrage an GitHub
Wirf eine PATCH-Anfrage mit HttpURLConnection
Beachten Sie Folgendes, wenn Sie Apache PDFBox® mit AWS Lambda verwenden
Senden Sie nach eindeutiger Authentifizierung mit Spring Cloud Gateway eine Anfrage an das Backend
Hinweise zur Vorgehensweise beim Auftreten einer WebView ClassNotFoundException in JavaFX 12