Почему значения объекта DOM формы не обновляются в этом коде? - PullRequest
0 голосов
/ 25 июня 2019

Я использую JavaScript для генерации контрольной суммы пароля с помощью встроенной функции SubtleCrypto.digest().Эта функция возвращает результат в виде объекта promise, который затем передается встроенной функции, которая преобразует результат в текстовое представление шестнадцатеричных байтов.Проблема заключается в том, что встроенная функция преобразования текста digToHex() не обновляет скрытые поля в DOM, которые затем отправляются на сервер в запросе POST.

Функция вызывается с помощью присоединенного события onclick()на кнопку в форме.Он считывает введенный пользователем в форму пароль и передает его в функцию digestMsg() для генерации хеша.

Обратите внимание, что мне известны проблемы безопасности, связанные с SHA-1.В настоящее время это только подтверждение концепции.

Я наблюдал вывод в инструментах разработчика Chrome, как на консоли, так и на вкладке сети.Я также отслеживал входящий запрос на сервере (IOT-устройстве).Представленные значения всегда нулевые.Кажется, что функция digToHex() генерирует хэш, потому что хэш отображается как значение chk.value на вкладке консоли.Как видно из кода, я пробовал назначения и отправку форм как вне, так и внутри контекста обработчика обещаний digestMsg().

function reboot() {
    var msg = document.querySelector('#pwd1').value;

    // Test purposes only
    var opt = document.querySelector('[name = "opt"]');
    var chk = document.querySelector('[name = "chk1"]');
    // Test purposes only

    digestMsg(msg).then(result=>{
        var opt = document.querySelector('[name = "opt"]');
        var chk = document.querySelector('[name = "chk1"]');
        opt.value = 3;
        chk.value = digToHex(result);
        // document.querySelector('form').submit();

    console.log(opt.value);
    console.log(chk.value);

    });
    // form.submit();

    alert("Result: " + opt.value + " - " + chk.value);
}

function digToHex(buf) {
    const bytes = new Uint8Array(buf);
    const hexCodes = [...bytes].map(value => {
        const hexCode = value.toString(16);
        const padHexCode = hexCode.padStart(2, '0');
        return padHexCode;
    });
    return hexCodes.join('');
}

function digestMsg(msg) {
    const enc = new TextEncoder();
    const data = enc.encode(msg);
    return window.crypto.subtle.digest('SHA-1', data);
}

Когда одна из двух строк sumbit() не была закомментирована,null значения были получены на сервере, но инструменты разработчика Chrome показывают правильные значения на выходе консоли.Дальнейшее изучение вкладки сетевого вывода в инструментах разработчика подтверждает, что нулевые значения фактически передаются.Я ожидаю увидеть "opt" со значением 3 и chk1 со значением, содержащим хэш.

Это HTML-код, вызывающий код:

<form method="post" action="/admin">
<input name="chk1" value="" hidden/>
<input name="chk2" value="" hidden/>
<input name="opt" value=0 hidden/>
<table>
<tr><th>Current password:</th><td><input id="pwd1" type="password">        </input></input></td>
<tr><th>New password:</th><td><input id="pwd2" type="password"></input></input></td>
<tr><th>Confirm new password:</th><td><input id="pwd3" type="password"></input></input></td>
<tr><th></th><td align="right"><input type="submit" class="btn" value="Change" onclick="change()"/></td></tr>
<tr><th></th><td><br></td></tr>
<tr><th>Defaults</th><td align="right"><input type="submit" class="btn" value="Reset" onclick="reset()"/></td></tr>
<tr><th>Restart WiFi</th><td align="right"><input type="button" class="btn" value="Reboot" onclick="reboot()"/></td></tr>
</table>
</form>

Далеетестирование в соответствии с Marius показывает, что код действительно работает со статической HTML-страницей.Следовательно, проблема может быть связана с тем, как я динамически загружаю html для каждой формы.Я прилагаю HTML для главной (родительской) страницы ниже:

<html>
<head>
<meta charset="utf-8">
<title>AR488 WiFi Configuration</title>
<link rel="stylesheet" href="AR488wifi.css">
<script defer src="AR488wifi.js"></script> 
</head>
<body onload="getPage('seeStat.html')";>
<div class="mpage">
<div class="headr">AR488 WiFi Configuration</div>
<div>
<ul>
<li id="mStat" class="active"><a onclick="getPage('seeStat.html')">Status</a></li>
<li id="mGen"><a onclick="getPage('cfgGen.div')">General</a></li>
<li id="mWifi"><a onclick="getPage('cfgWifi.div')">WiFi</a></li>
<li id="m488"><a onclick="getPage('cfg488.div')">GPIB</a></li>
<li id="mAdm"><a onclick="getPage('cfgAdm.div')">Admin</a></li>
</ul>
</div>
<hr>
<div id="cfgPage" class="conf">
</div>
<div>
<hr>
<table class="foot"><tr>
<td>AR488 WiFi ver: 0.00.00</td>
<td>Firmware ver: 0.00.00</td>
</tr></table>
</div>
</div>
</body>
</html>

Ответы [ 2 ]

0 голосов
/ 26 июня 2019

Я считаю, что нашел решение!

В моем исходном коде я использовал querySelector () для получения ссылки на объект формы, который был немедленно передан для отправки, но после обработки было сделано:

document.querySelector('form').submit();

Форма была отправлена ​​с параметром «opt», установленным в «0» - числовое значение, которое я специально установил - не ноль или неопределенное значение, поэтому эта команда создала ссылкуисходной неизмененной форме, которая затем была немедленно отправлена.

Я экспериментировал, создавая ссылку на форму в контексте обработчика digestMsg () до того, как обработка была выполнена с помощью:

var formObj = document.querySelector('form');

После обработки формы и обновления значений она была отправлена ​​с:

formObj.submit();

На этот раз форма отправлена ​​с правильными обновленными значениями.Скорректированный код (за исключением различных тестовых предупреждений) теперь выглядит следующим образом:

function reboot() {
    var msg = document.querySelector('#pwd1').value;
    digestMsg(msg).then(result=>{
        var formObj = document.querySelector('form');
        var opt = document.querySelector('[name = "opt"]');
        var chk = document.querySelector('[name = "chk1"]');
        opt.value = 3;
        chk.value = digToHex(result);
        formObj.submit();
    });
}

Мне было бы интересно узнать, ПОЧЕМУ первая команда создала ссылку на исходную измененную форму и не приняла во внимание обновленные значения?В обоих случаях все происходит в одном и том же порядке - форма загружается в браузер, значения обновляются и форма отправляется.Кроме того, почему оригинальная версия работала со статической HTML-страницей, но не с динамически загружаемой формой?Если у кого-то есть объяснение, я бы с нетерпением его услышал.

А пока спасибо за полезные комментарии, которые помогли мне сосредоточиться и прийти к решению.

Выше приведеноДля получения фактической рабочей формы потребуется лишь подтверждение концепции, а также дальнейшая проверка и корректировка.

0 голосов
/ 25 июня 2019

Ваш код выглядит нормально. Я скопировал то, что у вас есть, и добавил немного HTML, чтобы смоделировать это. Убедитесь, что поля не отключены.

reboot();

function reboot() {
    var msg = document.querySelector('#pwd1').value;

    // Test purposes only
    var opt = document.querySelector('[name = "opt"]');
    var chk = document.querySelector('[name = "chk1"]');
    // Test purposes only

    digestMsg(msg).then(result=>{
        var opt = document.querySelector('[name = "opt"]');
        var chk = document.querySelector('[name = "chk1"]');
        opt.value = 3;
        chk.value = digToHex(result);

    console.log(opt.value);
    console.log(chk.value);

    });

}

function digToHex(buf) {
    const bytes = new Uint8Array(buf);
    const hexCodes = [...bytes].map(value => {
        const hexCode = value.toString(16);
        const padHexCode = hexCode.padStart(2, '0');
        return padHexCode;
    });
    return hexCodes.join('');
}

function digestMsg(msg) {
    const enc = new TextEncoder();
    const data = enc.encode(msg);
    return window.crypto.subtle.digest('SHA-1', data);
}
<input type="password" id="pwd1" value="test" />
<input type="text" name="opt" />
<input type="text" name="chk1" />
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...