Поиск и автоматическое заполнение форм входа в HTML в UIWebView с использованием JavaScript
У меня есть UIWebView, который действует как интернет-браузер и загружает HTML-страницы веб-страниц, на которых он находится.
в webViewController, метод webViewDidFinishLoad, загрузил бы HTML с веб-страницы, когда веб-страница завершит загрузку в UIWebView.
Из HTML я бы хотел, чтобы сито выводило текстовые поля, чтобы облегчить автоматическую совокупность этого текстового поля со значениями, хранящимися в моей базе данных.
Любые методы для этого? Метод должен иметь возможность работать на всех веб-сайтах.
Установить текст для текстового поля в UIWebView почти что может мне помочь, но я пробовал его, и текстовое поле никогда не заполнялось.
На странице входа в систему будут два текстовых поля
поэтому я попытался использовать
document.getElementsByTagName('INPUT')[0].value
document.getElementsByTagName('INPUT')[1].value
для ввода значений, но без магии.
Изменить:
Я пробовал другое положение в массиве. имя пользователя и пароль для Facebook - [3] и [4], тогда как для амазонки это [11] и [14].
поэтому положение того, где поля используют вышеупомянутый метод, является случайным. Любое другое предложение, которое будет работать для всего веб-сайта?
Edit2:
я мог попробовать
document.getElementsById('id_name').value
но метод ID не будет работать для меня, поскольку мне нужен универсальный метод, который будет идентифицировать текстовые поля на любых веб-сайтах (все веб-сайты используют разные идентификационные имена)
Также мне кажется, что некоторые веб-сайты последовательно устанавливают этот tabindex = "1" для имени пользователя и tabindex = "2" для пароля.
например, на веб-странице, например Facebook:
<input type="text" class="inputtext" name="email" id="email" value="" tabindex="1" />
<input type="password" class="inputtext" name="pass" id="pass" tabindex="2" />
амазонка:
<input id="ap_email" name="email" value="" type="email" size="30" maxlength="128" tabindex="1" autocorrect="off" autocapitalize="off" />
<input id="ap_password" name="password" type="password" maxlength="1024" size="20" tabindex="2" onkeypress="displayCapsWarning(event,'ap_caps_warning', this);" class="password"/>
dbs bank:
<input type="text" tabindex="1" maxlength="20" size="32" name="UID" id="UID">
<input type="password" onkeyup="keyUp(event)" onkeydown="return onlyNumerics(event)" tabindex="2" maxlength="9" size="32" name="PIN" id="PIN" autocomplete="off">
но я не видел этот tabindex в google:
<input type="text" spellcheck="false" name="Email" id="Email" value="">
<input type="password" name="Passwd" id="Passwd">
любое предложение?
Конечная цель состоит в том, чтобы иметь возможность вычеркивать поле имени пользователя и пароля для всех/любых веб-сайтов. =)
Ответы
Ответ 1
ОК, так что для этого нет единого размера. Вы можете получить довольно близко, но он никогда не будет работать на каждом веб-сайте, поскольку на веб-сайте может быть несколько форм входа или несколько полей, которые составляют имя пользователя (некоторые банки имеют это).
Но это поможет вам в правильном направлении. Чтобы получить все поля пароля (в основном только одно), используйте это:
document.querySelectorAll("input[type='password']")
Чтобы получить все поля ввода текста, используйте это:
document.querySelectorAll("input[type='text']")
Для полей ввода текста вы, скорее всего, получите несколько результатов (возможно, поля поиска и прочее). Таким образом, вам придется перебирать их и искать общие идентификаторы или имена, такие как "имя пользователя", "пользователь", "имя пользователя", "UID" и т.д.
Вот как вы могли бы использовать его в Objective-C:
- (void)webViewDidFinishLoad:(UIWebView *)webView {
NSString *savedUsername = @"peter";
NSString *savedPassword = @"Pan123";
if (savedUsername.length != 0 && savedPassword.length != 0) {
//create js strings
NSString *loadUsernameJS = [NSString stringWithFormat:@"var inputFields = document.querySelectorAll(\"input[type='text']\"); \
for (var i = inputFields.length >>> 0; i--;) { inputFields[i].value = '%@';}", savedUsername];
NSString *loadPasswordJS = [NSString stringWithFormat:@"document.querySelectorAll(\"input[type='password']\").value ='%@'", savedPassword];
//autofill the form
[self.webView stringByEvaluatingJavaScriptFromString: loadUsernameJS];
[self.webView stringByEvaluatingJavaScriptFromString: loadPasswordJS];
}
}
Обратите внимание: он заполняет каждое текстовое поле именем пользователя и только первым паролем с паролем.
Enjoy.
Ответ 2
Основываясь на предыдущем ответе, я создал эти 3 метода.
Этот метод заполнит поля имени пользователя/электронной почты, которые должны работать во многих случаях:
- (void)completeUserFieldsForWebView:(UIWebView *)webView withUsername:(NSString *)username {
NSString *loadUsernameJS =
[NSString stringWithFormat:@"var inputFields = document.querySelectorAll(\"input[type='email']\"); \
for (var i = inputFields.length >>> 0; i--;) { inputFields[i].value = '%@';}", username];
NSString *loadText =
[NSString stringWithFormat:@"var inputFields = document.querySelectorAll(\"input[type='text']\"); \
for (var i = inputFields.length >>> 0; i--;) { inputFields[i].value = '%@';}", username];
[webView stringByEvaluatingJavaScriptFromString: loadUsernameJS];
[webView stringByEvaluatingJavaScriptFromString: loadText];
}
В этом поле будут заполнены поля пароля:
- (void)completePasswordFieldsForWebView:(UIWebView *)webView withPassword:(NSString *)password {
NSString *loadPasswordJS =
[NSString stringWithFormat:@"var passFields = document.querySelectorAll(\"input[type='password']\"); \
for (var i = passFields.length>>> 0; i--;) { passFields[i].value ='%@';}", password];
[webView stringByEvaluatingJavaScriptFromString: loadPasswordJS];
}
И чтобы выполнить вход:
- (void)clickOnSubmitButtonForWebView:(UIWebView *)webView {
NSString *performSubmitJS = @"var passFields = document.querySelectorAll(\"input[type='submit']\"); \
passFields[0].click()";
[webView stringByEvaluatingJavaScriptFromString:performSubmitJS];
}
Ответ 3
Я не думаю, что найти ссылку на входные элементы будет сложно с помощью javascript, но это исправляет их, что не просто с UIWebView.
Хакерный способ добиться того, что вы хотите в том, как вы описываете, можно сделать, получив HTML из UIWebView, изменив его, а затем загрузив обратно. Например:
// Get the HTML from the UIWebView
NSMutableString *html = [[[self.webView stringByEvaluatingJavaScriptFromString:@"document.documentElement.outerHTML;"] mutableCopy] autorelease];
// Find the range of the first input element.
NSRange firstInputRange = [html rangeOfString:@"<input" options:NSCaseInsensitiveSearch];
// Check if it was found...
if (firstInputRange.location != NSNotFound) {
// Add replace with the populated value attribute appended.
[html replaceCharactersInRange:firstInputRange withString:@"<input value='username'"];
// Now do the same for the second input range, checking the html after the first input.
NSRange secondInputRange = [html rangeOfString:@"<input" options:NSCaseInsensitiveSearch range:NSMakeRange(firstInputRange.location+firstInputRange.length, html.length - firstInputRange.location - firstInputRange.length)];
// And if found, append the populated value attribute.
if (secondInputRange.location != NSNotFound) {
[html replaceCharactersInRange:secondInputRange withString:@"<input value='password'"];
}
}
// Finally, load the amended HTML back into the UIWebView/
[self.webView loadHTMLString:html baseURL:nil];
Ответ 4
У меня возникли проблемы с поиском полей, поэтому я адаптировал код для более конкретных целей:
- (void)webViewDidFinishLoad:(UIWebView*)theWebView
{
NSString *savedUsername = @"username";
NSString *savedPassword = @"pass";
if (savedUsername.length != 0 && savedPassword.length != 0) {
NSString *loadUsernameJS = [NSString stringWithFormat:@"var inputFields = document.getElementsByTagName('input'); \
for (var i = inputFields.length >>> 0; i--;) { if(inputFields[i].name == 'username') inputFields[i].value = '%@';}", savedUsername];
NSString *loadPasswordJS = [NSString stringWithFormat:@" \
for (var i = inputFields.length >>> 0; i--;) { if(inputFields[i].name == 'password') inputFields[i].value = '%@';}", savedPassword];
//autofill the form
[theWebView stringByEvaluatingJavaScriptFromString: loadUsernameJS];
[theWebView stringByEvaluatingJavaScriptFromString: loadPasswordJS];
}
return [super webViewDidFinishLoad:theWebView];
}