- PVSM.RU - https://www.pvsm.ru -
В статье мы попытаемся описать два совершенно не связанных с собой аспекта децентрализованных одностраничных приложений. Это соединение двух пользователей и сохранение паролей в одностраничном приложении при помощи браузера.
Информация об используемой технологии WebRTC — webrtc.org [1]. В браузере весь смысл общения завязан на этой технологии, а точнее на WebRTC API [2] которое доступно для Front-end разработчика.
Одной из целей было создать децентрализованный чат, чат без использования сервера. Однако, сервер оказался просто необходим для реализации следующих возможностей:
Рассмотрим детально схему соединения для двух пользователей. Для этого выделим основные шаги в обычной схеме соединения Клиента А и Клиента Б:
Выделенные слова в трех случаях как раз показывают зачем нужен сервер на начальном этапе соединения. Для обмена данными через сервер.
В нашем чате оба клиента одновременно могут выступать инициаторами соединения, но в результате мы все равно хотим получить лишь одно соединение RTCDataChannel между двумя клиентами. Сигнальный сервер конечно может указать какому клиенту выступать инициатором — а какому ждать предложение. Но для минимизации ошибки при соединении мы запускаем механизм в котором каждый из клиентов является инициирующем и принимающем одновременно. В результате оставляем то соединение клиент-клиент, которое образуется быстрее. Рассмотрим более детально этот аспект.
Ниже представлена схема соединения двух инициирующих/принимающих клиентов.
Таким образом при инициировании соединения двумя клиентами, между ними будет всего один RTCDataChannel, а не два.
При работы с приложением каждый пользователь проходит следующие этапы:
Для этого в приложении были предусмотрены три страницы, каждая из которых предназначена для соответствующего этапа (структура сайта):
Но страницы генерируются на клиенте, а для перехода между ними используется HistoryAPI [4]. Важным моментом для удобства использования приложения, является сохранение авторизационных данных пользователя в браузере (пароля), используя при этом поведение браузера по умолчанию.
В нашем случае, введенные данные пользователя должны предлагаться к сохранению для формы логина при смене url с "/login" на "/chat", а при смене "/login" на "/register" не должны предлагаться. На практике это оказалось невозможно реализовать. Сохранение предлагалось и при переходе с "/login" на "/register" и с "/register" на "/login". Таким образом задача заключалась в отмене сохранения данных в браузере для определенных случаев.
Для решения данного вопроса были использованы различные методы, которые представлены ниже.
Чтобы отключить автозаполнение на странице регистрации, устанавливаем для всей формы атрибут 'autocomplete' со значением 'off'.
Разметка для данного варианта:
<form autocomplete="off" data-role="loginForm">
<label>Имя пользователя:</label>
<input type="text" name="userName">
<label>Пароль пользователя:</label>
<input type="password" name="userPassword">
<button type="submit">Войти</button>
</form>
Ссылка на данный вариант решения stackoverflow.com/a/468295 [5].
Пробовали отключить автозаполнение на странице регистрации установив атрибут 'autocomplete' со значением 'off' для полей input, то есть имени и пароля пользователя.
Разметка для данного варианта:
<form data-role="loginForm">
<label>Имя пользователя:</label>
<input type="text" name="userName" autocomplete="off">
<label>Пароль пользователя:</label>
<input type="password" name="userPassword" autocomplete="off">
<button type="submit">Войти</button>
</form>
В предыдущей ссылке обсуждается и этот вариант.
Данный вариант предполагает добавление в разметку скрытого элемента div, который включает в себя поля имени и пароля пользователя, которые всегда будут оставаться пустыми. Разметка для данного варианта:
<form data-role="loginForm">
<div style={{display:'none'}}>
<input type="text" />
<input type="password" />
</div>
<label>Имя пользователя:</label>
<input type="text" name="userName" autocomplete="off">
<label>Пароль пользователя:</label>
<input type="password" name="userPassword" autocomplete="off">
<button type="submit">Войти</button>
</form>
Ссылка на данный вариант решения stackoverflow.com/a/25111774 [6]. Аналогичное решение предложено и в данном [7] источнике.
В данном варианте прибегаем к помощи js. При клике пользователя на кнопку «Войти» по событию submit выполняем обнуление полей имени и пароля.
Программный код:
handleSubmit: function(event) {
this.loginForm = document.querySelector('[data-role="loginForm"]');
event.preventDefault();
this.loginForm.elements.userName.value = '';
this.loginForm.elements.userPassword.value = '';
}
Обнуление данных выполнялось как сразу после клика, так и через некоторый интервал времени ( SetTimeout() ).
Последний из вариантов заключается в создании новой кнопки в форме, которая бы выполняла роль кнопки submit.
Разметка данного варианта:
<form data-role="loginForm">
<label>Имя пользователя:</label>
<input type="text" name="userName" autocomplete="off">
<label>Пароль пользователя:</label>
<input type="password" name="userPassword" autocomplete="off">
<button type="button" data-action="submit" onclick="handleClick">Войти</button>
</form>
Программный код:
handleClick(event) {
if (event.target.dataset.action === 'submit'){
history.pushState({foo: 'bar'}, 'Title', '/chat')
}
}
Все вышеприведенные способы не позволяли при одном переходе сохранять пароль, а при другом не сохранять. Можно было либо сохранять всегда, либо не сохранять никогда.
Отсюда конечно о наболевшем, что давно пора для одностраничных приложений сделать JS API для браузера о сохранении пароля:
window.navigator.promtPasswordSave()
Что-то вроде этого было бы замечательно.
В настоящее время в качестве решения рассматриваемого вопроса в приложении была изменена структура сайта на следующую:
Где страница /account имеет два внутренних состояния login и register, в зависимости от этого состояния мы и генерируем ту или иную разметку. Только так мы смогли решить проблему с контролируемым сохранением пароля в браузере.
SPACHAT (Single Page Application Chat) — веб приложение для обмена сообщениями между клиентами с помощью технологии WebRTC, которое мы и реализовываем. Реализованное приложение или просто чат можно посмотреть на сайте spachat.net [8].
Непосредственно сам код доступны по ссылке github.com/volodalexey/spachat [9].
Автор: volodalexey
Источник [10]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/javascript/215375
Ссылки в тексте:
[1] webrtc.org: https://webrtc.org/
[2] WebRTC API: https://developer.mozilla.org/ru/docs/Web/API/WebRTC_API
[3] RTCDataChannel: https://developer.mozilla.org/ru/docs/Web/API/RTCDataChannel
[4] HistoryAPI: https://developer.mozilla.org/ru/docs/Web/API/History_API
[5] stackoverflow.com/a/468295: http://stackoverflow.com/questions/468288/input-type-password-dont-let-browser-remember-the-password/468295#468295
[6] stackoverflow.com/a/25111774: http://stackoverflow.com/questions/32369/disable-browser-save-password-functionality/25111774#25111774
[7] данном: http://www.zigpress.com/2014/11/22/stop-chrome-messing-forms/
[8] spachat.net: https://spachat.net
[9] github.com/volodalexey/spachat: https://github.com/volodalexey/spachat
[10] Источник: https://habrahabr.ru/post/316556/?utm_source=habrahabr&utm_medium=rss&utm_campaign=sandbox
Нажмите здесь для печати.