В нашем проекте Android
(менеджер загрузок) нам нужно показать встроенный веб-браузер, чтобы мы могли отслеживать загрузки со всеми данными (заголовками, файлами cookie, данными постов), чтобы мы могли обрабатывать их должным образом.
К сожалению, WebView
элемент управления, который мы используем, не обеспечивает никакого доступа к POST
данным запросов, которые он делает. Поэтому мы используем хакерский способ получить эти данные. Мы вводим этот код javascript
в каждый код html
, загружаемый браузером:
<script language="JavaScript">
HTMLFormElement.prototype._submit = HTMLFormElement.prototype.submit;
HTMLFormElement.prototype.submit = formSubmitMonitor;
window.addEventListener('submit', function(e) {
formSubmitMonitor(e);
}, true);
function formSubmitMonitor(e) {
var frm = e ? e.target : this;
formSubmitMonitor_onsubmit(frm);
frm._submit();
}
function formSubmitMonitor_onsubmit(f) {
var data = "";
for (i = 0; i < f.elements.length; i++) {
var name = f.elements[i].name;
var value = f.elements[i].value;
//var type = f.elements[i].type;
if (name)
{
if (data !== "")
data += '&';
data += encodeURIComponent(name) + '=' + encodeURIComponent(value);
}
}
postDataMonitor.onBeforeSendPostData(
f.attributes['method'] === undefined ? null : f.attributes['method'].nodeValue,
new URL(f.action, document.baseURI).href,
data,
f.attributes['enctype'] === undefined ? null : f.attributes['enctype'].nodeValue);
}
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) {
if (body)
{
postDataMonitor.onBeforeSendPostData(
this.recordedMethod,
this.recordedUrl,
body,
null);
}
this.origSend(body);
};
const origFetch = window.fetch;
window.fetch = function()
{
postDataMonitor.onBeforeSendPostData(
"POST",
"test",
"TEST",
null);
return origFetch.apply(this, arguments);
}
</script>
Как правило, он работает нормально.
Но в веб-интерфейсе Почты Google это не работает по неизвестной причине. Например, когда пользователь вводит свое имя пользователя и нажимает Next
. Я думал, что он использует Fetch API
, поэтому я добавил перехват для него тоже. Но это не помогло. Обратите внимание, что нам не нужно перехватывать учетные данные пользователя, но мы должны иметь возможность перехватывать все или ничего. К сожалению, так работает вся система ...
Добавление №1. Я нашел другой способ: не переопределять shouldInterceptRequest
, но переопределять onPageStarted
вместо этого и позвоните evaluateJavascript
там. Таким образом, это работает даже на веб-сайте Google Mail! Но почему первый метод не работает тогда? Мы как-то нарушаем HTML код?