Поиск и автоматическое заполнение форм входа в HTML в UIWebView с использованием JavaScript - PullRequest
11 голосов
/ 15 марта 2012

У меня есть UIWebView, который работает как интернет-браузер и загружает HTML веб-страниц, на которых он находится.

в webViewController, метод webViewDidFinishLoad, загрузил бы HTML-код с веб-страницы после завершения загрузки веб-страницы в UIWebView.

Из HTML я хотел бы просеять текстовые поля, чтобы упростить автоматическое заполнение этого текстового поля значениями, хранящимися в моей базе данных.

Есть ли способы сделать это? Метод должен работать на всех сайтах.

Установить текст для текстового поля в UIWebView имеет почти то, что может мне помочь, но я пробовал это, и текстовое поле так и не было заполнено.

На странице входа будут два текстовых поля поэтому я попытался использовать

document.getElementsByTagName('INPUT')[0].value
document.getElementsByTagName('INPUT')[1].value 

для ввода значений, но без магии.

Edit: я пробовал другую позицию в массиве. имя пользователя и пароль для Facebook - [3] и [4], тогда как для amazon это [11] и [14]. таким образом, положение полей, в которых используется вышеуказанный метод, является случайным. Любое другое предложение, которое будет работать для всего сайта?

Edit2: я мог бы попробовать

document.getElementsById('id_name').value

, но метод ID не будет работать для меня, так как мне нужен универсальный метод, который будет идентифицировать текстовые поля на любых веб-сайтах (все сайты используют разные имена 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"/> 

банк базы данных:

<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">

есть предложения?

Конечная цель состоит в том, чтобы иметь возможность просеивать поля Имя пользователя и Текстовый пароль для всех / любых веб-сайтов. =)

Ответы [ 4 ]

17 голосов
/ 15 марта 2012

ОК, так что для этого не существует единого размера. Вы можете подойти довольно близко, но он никогда не будет работать на каждом веб-сайте, поскольку веб-сайт может иметь несколько форм входа в систему или несколько полей, которые составляют имя пользователя (в некоторых банках это есть).

Но это приведет вас в правильном направлении. Чтобы получить все поля пароля (в основном только одно), используйте это:

document.querySelectorAll("input[type='password']")

Чтобы получить все поля ввода текста, используйте это:

document.querySelectorAll("input[type='text']")

Для полей ввода текста, скорее всего, вы получите несколько результатов (возможно, полей поиска и прочего). Поэтому вам придется перебирать их и искать общие идентификаторы или имена, такие как «username», «user», «user_name», «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];
    }
}

Обратите внимание: он заполняет каждое текстовое поле именем пользователя и только первое поле пароля с паролем.

Наслаждайтесь.

5 голосов
/ 21 апреля 2014

Основываясь на предыдущем ответе, я создал эти 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];

} 
0 голосов
/ 05 марта 2014

У меня были некоторые проблемы с поиском полей, поэтому я адаптировал код для более точного назначения полей:

   - (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];
  }      
0 голосов
/ 15 марта 2012

Я не думаю, что найти ссылку на элементы ввода будет сложно с помощью 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];
...