Я пытаюсь перехватить POST-запрос перед открытием HTML страницы с помощью webView. Я следовал руководству: https://medium.com/@madmuc / intercept-all-network-traffi c -in-webkit-on- android -9c56c9262c85 , в котором файл javascript вводится через. js файл в папке активов:
XMLHttpRequest.prototype.origOpen = XMLHttpRequest.prototype.open;
XMLHttpRequest.prototype.open = function(method, url, async, user, password) {
// these will be the key to retrieve the payload
this.recordedMethod = method;
this.recordedUrl = url;
this.origOpen(method, url, async, user, password);
};
XMLHttpRequest.prototype.origSend = XMLHttpRequest.prototype.send;
XMLHttpRequest.prototype.send = function(body) {
// interceptor is a Kotlin interface added in WebView
if(body) recorder.recordPayload(this.recordedMethod, this.recordedUrl, body);
this.origSend(body);
};
Однако, open и send никогда не вызываются, я добавил журналы для проверки, и если я переместил recorder.recordPayload(...)
(это метод в интерфейсе javascript ) из этих функций вызывается recordPayload
, поэтому проблема не в интерфейсе или чтении из файла.
класс webView:
class TestWebView : WebView {
private var urlReturned = false
private var postbackUrl: String? = "https://www.xxxxx.com"
private var postbackHandled = false```
lateinit var recorder: PayloadRecorder
lateinit var payload: String
constructor(context: Context?) : super(context) {
initUI()
}
private fun initUI() {
if (!isInEditMode) {
settings.javaScriptEnabled = true
settings.builtInZoomControls = true
settings.displayZoomControls = false
settings.loadWithOverviewMode = true
settings.useWideViewPort = true
recorder = PayloadRecorder()
addJavascriptInterface(recorder, "recorder")
evaluateJavascript(
context.assets.open("override.js").reader().readText(), null
)
}
val client: WebViewClient = object : WebViewClient() {
override fun shouldInterceptRequest(
view: WebView,
request: WebResourceRequest
): WebResourceResponse? {
val payload = recorder.getPayload(request.method, request.url.toString())
// handle the request with the given payload and return the response
return super.shouldInterceptRequest(view, request)
}
override fun onPageStarted(
view: WebView,
url: String,
favicon: Bitmap?
) {
Log.i("testURL", url)
evaluateJavascript(
context.assets.open("override.js").reader().readText(),
object : ValueCallback<String> {
override fun onReceiveValue(value: String?) {
Log.i("onReceiveValue", value)
}
}
)
}
}
setWebChromeClient(object : WebChromeClient() {
override fun onConsoleMessage(consoleMessage: ConsoleMessage): Boolean {
Log.d("WebView", consoleMessage.message())
return true
}
})
}
constructor(context: Context?, attrs: AttributeSet?) : super(
context,
attrs
) {
initUI()
}
constructor(
context: Context?,
attrs: AttributeSet?,
defStyle: Int
) : super(context, attrs, defStyle) {
initUI()
}
constructor(
context: Context?,
attrs: AttributeSet?,
defStyle: Int,
privateBrowsing: Boolean
) : super(context, attrs, defStyle) {
initUI()
}
class PayloadRecorder {
private val payloadMap: MutableMap<String, String> =
mutableMapOf()
@JavascriptInterface
fun recordPayload(
method: String,
url: String,
payload: String
) {
payloadMap["$method-$url"] = payload
Log.i("payloadRecorder", "recordPayLoad")
}
fun getPayload(
method: String,
url: String
): String? =
payloadMap["$method-$url"]
}
/**
* The function that is called and starts the html progress
*/
@JvmOverloads
fun process(
acsUrl: String?,
md: String?,
paReq: String?,
postbackUrl: String? = null
) {
urlReturned = false
postbackHandled = false
if (!TextUtils.isEmpty(postbackUrl)) {
this.postbackUrl = postbackUrl
}
val postParams: String
payload = paReq?: ""
postParams = //my code
postUrl(acsUrl, postParams.toByteArray())
}
}
recordPayload
никогда не вызывается, поэтому в shouldInterceptRequest
payload
всегда возвращается ноль.