Как программно установить значение текстового поля пароля WebKit? - PullRequest
2 голосов
/ 24 января 2010

Обновление: этот вопрос является двухъярусным. Двигайся, здесь нечего видеть. Вы можете установить значение текстового поля пароля из JS или ObjC. Я был не прав.

У меня есть приложение Cocoa на основе WebKit, которое загружает HTML-документ, содержащий HTML-форму в WebView. HTML-форма содержит текстовое поле пароля, например:

<form name="foo">
    <input type="password" name="bar">
</form>

Я бы хотел установить значение этого текстового поля программно (если возможно, из Objective-C, но я сделаю все, что сработает).

Я считаю, что в WebKit (и во всех других современных браузерах) реализована функция безопасности JavaScript, которая не позволяет сценариям JS устанавливать это значение программным путем.

К сожалению, похоже, что такое же ограничение безопасности применимо к Objective-C, поскольку я не могу установить значение с помощью ObjC. Хотя ограничение JS является разумным, ObjC кажется немного неразумным.

Есть ли какой-либо способ программно установить значение этого поля (если не считать связывание настраиваемого WebKit в моем приложении, которое было изменено, чтобы разрешить это)? Я открыт для любых предложений.

Вот что я попробовал в ObjC:

DOMHTMLDocument *doc = (DOMHTMLDocument *)[webView mainFrameDocument];
DOMHTMLFormElement *formEl = (DOMHTMLFormElement *)[[doc forms] namedItem:@"foo"];
DOMHTMLInputElement *inputEl = (DOMHTMLInputElement *)[[formEl elements] namedItem:@"bar"];
[inputEl setValue:@"baz"];

это не имеет никакого эффекта.

Ответы [ 4 ]

5 голосов
/ 24 января 2010

Это определенно должно работать без необходимости прыгать через любые обручи, чтобы сделать это. Я только что написал быстрое тестовое приложение, которое загрузило http://mail.google.com/ и хорошо вошло в него со следующим кодом на SnowLeopard и Leopard:

- (void)webView:(WebView *)sender didFinishLoadForFrame:(WebFrame *)frame
{
    if (![[sender mainFrame] isEqual:frame])
        return;

    DOMHTMLFormElement *form = (DOMHTMLFormElement *)[[frame DOMDocument] getElementById:@"gaia_loginform"];
    DOMHTMLInputElement *username = (DOMHTMLInputElement *)[[form elements] namedItem:@"Email"];
    [username setValue:@"myemailacct"];

    DOMHTMLInputElement *password = (DOMHTMLInputElement *)[[form elements] namedItem:@"Passwd"];
    [password setValue:@"omghi"];

    [form submit];
}

У меня также есть очень похожий код на работе, единственной задачей которого является вход на веб-сайт, и он прекрасно работает на Tiger в течение года. В этом случае я делаю все, включая создание WebView через код. Я также был бы очень удивлен, если бы автозаполнение Safari не использовало подобный код.

Тем не менее, я хотел бы убедиться, что ваше приложение не делает ничего сумасшедшего с WebView. Делаете ли вы другие модификации DOM где-нибудь еще? Попробуйте сделать это в примере приложения, как я, и посмотрите, работает ли оно там.

Является ли HTML, который вы загружаете, своим или на удаленном сервере? Некоторые веб-сайты включают Javascript, который очищает поля формы при загрузке или через секунду или две после предотвращения автозаполнения. Может быть, вы сталкиваетесь с этим?

Если ничего не помогло, убедитесь, что в консоль WebView ничего не заносится. Это можно увидеть, открыв веб-инспектор или временно внедрив частный метод WebUIDelegate:

- (void)webView:(WebView *)webView addMessageToConsole:(NSDictionary *)message;
3 голосов
/ 24 января 2010

Ограничение, вероятно, связано с тем, что мост DOM подключается непосредственно к тому же коду, что и среда выполнения javascript, поэтому вам необходимо обойти любой мост javascript / DOM.

Возможно, вы могли бы установить фокус на поле (если мост позволяет это сделать) и отправлять события клавиатуры в WebView или Document View.

В качестве альтернативы, поскольку эти поля являются нативными компонентами OS X, вы потенциально можете напрямую с ними общаться (а исходный код WebKit должен помочь вам понять, как к ним добраться).

Извините, оба решения немного вовлечены, и я понятия не имею, работает ли это! Возможно, в списке рассылки webkitdev будет ответ, или вы можете попытаться спросить разработчика 1Password; -)

0 голосов
/ 24 января 2010

Я бы использовал -stringByEvaluatingJavaScriptFromString:.

Вот что я использовал (я добавил атрибут 'id' в поле, чтобы его было легче захватить):

[_webView stringByEvaluatingJavaScriptFromString: @"document.getElementById(\"bar\").value = \"hello\""];
0 голосов
/ 24 января 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...