Javascript-форум (https://javascript.ru/forum/)
-   Элементы интерфейса (https://javascript.ru/forum/dom-window/)
-   -   Проверка textarea на запрет ввода элементов ссылки (https://javascript.ru/forum/dom-window/82455-proverka-textarea-na-zapret-vvoda-ehlementov-ssylki.html)

Vaska 10.05.2021 08:03

Проверка textarea на запрет ввода элементов ссылки
 
Приветствую!

На странице есть форма отправки сообщений.
На сервере добавил проверку вводимого содержания на наличие элементов ссылки и все элементы ссылок или названия доменных имен вырезаются. Если сообщение содержало только ссылку, то сохраняется пустое сообщение, что не есть хорошо.
Для PHP использую выражение:
$exge = '@((https?://)?([-\\w]+\\.[-\\w\\.]+)+\\w(:\\d+)?(/([-\\w/_\\.]*(\\?\\S+)?)?)*)(?:[?&][^?$]+=[^?&]*)*@i';

Хотелось бы, что бы выражение можно было переписать под использование в скрипте. Это выражение очень хорошо режет любые варианты ссылок и названия доменных имен.

Нужно сделать проверку формы скриптом на странице, на содержание элементов ссылки и если такие элементы есть в поле textarea, тогда выводить сообщение "Ссылки запрещены" и сообщение не должно отправляться.

Сейчас на странице есть скрипт, который проверяет количество вводимых символов, подсчитывает их и если символов 0 или больше 200, тогда выводит под формой в dstype="error_msg" сообщение "Вы не указали вопрос" или "Вопрос не должен превышать 200 символов" и сообщение не отправляется. Это правильно. Если ошибок в форме нет, тогда сообщение должно отправляться.
Нужно, чтобы сообщение "Ссылки запрещены" выводилось в том же dstype="error_msg", если это не будет мешать выводу других сообщений об ошибке количества символов.
Заранее спасибо, откликнувшимся!

<form method="post" id="save_consult_form2" action='goods/save_consult'>
	<div class="comment-add"><textarea id="textfield3" name="content" type="text"></textarea></div>
	<div class="comment-act">
		<a href="JavaScript:void(0);" dstype="consult_submit" class="dss-btn">Отправить</a>
	</div>
	<span id="consultcharcount"></span> <span dstype="error_msg"></span>
</form>


$(function () {
		$('a[dstype="consult_submit"]').click(function () {
			$('#save_consult_form2').submit();
		});
		
		$('#save_consult_form2').validate({
			errorPlacement: function (error, element) {
				$('span[dstype="error_msg"]').append(error);
			},

			submitHandler: function (form) {
				ds_ajaxpost('save_consult_form2');				
				},
				
			onkeyup: false,
			rules: {
				content: {
					required: true,
					maxlength: 200
				}
			},
            messages : {
                content : {
                    required : 'Вы не указали вопрос',
                    maxlength:'Вопрос не должен превышать 200 символов.'
				}
			}
		});
		
		// textarea подсчет символов
		$("#textfield3").charCount({
			allowed: 200,
			warning: 10,
			counterContainerID: 'consultcharcount',
			firstCounterText: 'Вы можете ввести ещё до',
			endCounterText: 'символов.',
			errorCounterText: 'Текст вопроса превышен на'
		});
	});

рони 10.05.2021 10:01

Vaska,
искать по форуму или документации $.validator.addMethod смотреть примеры.

рони 10.05.2021 11:23

validate запрет ссылок
 
Vaska,

<!DOCTYPE html>
<html>
<head>
    <title>Untitled</title>
    <meta charset="utf-8">
    <style type="text/css">
    </style>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.2/jquery.validate.min.js"></script>
    <script>
        $(function() {
            $('a[dstype="consult_submit"]').click(function() {
                $('#save_consult_form2').submit();
            });
            $.validator.addMethod('removeLink', function(value, element) {
                    return !/(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|(www\.)?[a-zA-Z0-9]+\.[^\s]{2,})/i.test(value)
                },
                'Ссылки запрещены');
            $('#save_consult_form2').validate({
                errorPlacement: function(error, element) {
                    $('span[dstype="error_msg"]').append(error);
                },
                submitHandler: function(form) {
                    ds_ajaxpost('save_consult_form2');
                },
                onkeyup: false,
                rules: {
                    content: {
                        required: true,
                        maxlength: 200,
                        removeLink: true
                    }
                },
                messages: {
                    content: {
                        required: 'Вы не указали вопрос',
                        maxlength: 'Вопрос не должен превышать 200 символов.'
                    }
                }
            });
        });
    </script>
</head>
<body>
    <form method="post" id="save_consult_form2" action='goods/save_consult'>
        <div class="comment-add"><textarea id="textfield3" name="content" type="text"></textarea></div>
        <div class="comment-act">
            <a href="JavaScript:void(0);" dstype="consult_submit" class="dss-btn">Отправить</a>
        </div>
        <span id="consultcharcount"></span> <span dstype="error_msg"></span>
    </form>
</body>
</html>

Vaska 10.05.2021 16:54

рони,спасибо, за помощь!
В целом скрипт работает, как я хотел.
Но есть проблема в выражении.
Переписанное выражение, для скрипта, не видит название домена, как ошибку, в тексте, например javascript.ru и пропускает его для отправки сообщения. Выражение для PHP видит название домена и вырезает его при записи в базу данных.
Можете пересмотреть выражение и поправить его для скрипта правильно?

рони 10.05.2021 17:05

Цитата:

Сообщение от Vaska
Можете пересмотреть выражение и поправить его?

поправил, если не подошло, ищите в сборниках RegExp и в целом по инету

Vaska 10.05.2021 17:22

рони,
Сейчас работает.
Спасибо, за помощь!

Vaska 10.05.2021 20:35

рони,
Можно ли добавить в ваше регулярное выражение условие: кроме ссылок содержащих доменное имя javascript.ru, или содержащее доменное имя subdomain.javascript.ru?
Я посмотрел в интернете, но такую конструкцию я сам не осилил добавить.

рони 10.05.2021 21:35

запрет ссылок кроме содержащих javascript.ru
 
Vaska,
<!DOCTYPE html>
<html>
<head>
    <title>Untitled</title>
    <meta charset="utf-8">
    <style type="text/css">
    </style>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.2/jquery.validate.min.js"></script>
    <script>
        $(function() {
            $('a[dstype="consult_submit"]').click(function() {
                $('#save_consult_form2').submit();
            });
            $.validator.addMethod('removeLink', function(value, element) {
                    let reg = /(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|(www\.)?[a-zA-Z0-9]+\.[^\s]{2,})/mig
                    let match = value.match(reg);  
                    return  !match || match.every(link  => link.includes('javascript.ru'))
                },
                'Сообщение содержит запрещённые ссылки');
            $('#save_consult_form2').validate({
                errorPlacement: function(error, element) {
                    $('span[dstype="error_msg"]').append(error);
                },
                submitHandler: function(form) {
                    ds_ajaxpost('save_consult_form2');
                },
                onkeyup: false,
                rules: {
                    content: {
                        required: true,
                        maxlength: 200,
                        removeLink: true
                    }
                },
                messages: {
                    content: {
                        required: 'Вы не указали вопрос',
                        maxlength: 'Вопрос не должен превышать 200 символов.'
                    }
                }
            });
        });
    </script>
</head>
<body>
    <form method="post" id="save_consult_form2" action='goods/save_consult'>
        <div class="comment-add"><textarea id="textfield3" name="content" type="text" rows="10"  cols="70">
         javascript.ru
         https://cdnjs.cloudflare.com/ajax   //для теста удалить эту строку
         https://www.javascript.ru
        </textarea></div>
        <div class="comment-act">
            <a href="JavaScript:void(0);" dstype="consult_submit" class="dss-btn">Отправить</a>
        </div>
        <span id="consultcharcount"></span> <span dstype="error_msg"></span>
    </form>
</body>
</html>

Vaska 10.05.2021 21:47

рони,
с тестовым содержимым формы выражение правильно отрабатывает.
Однако, если удалить всё содержимое, оставить только javascript.ru, нажать кнопку "Отправить", далее изменить javascript.ru на sjavascript.ru - тогда разрешает стороннему домену пройти проверку и сообщение отправляется. Это неправильно.

рони 10.05.2021 21:49

Vaska,
запрет ссылок кроме содержащих javascript.ru

Vaska 10.05.2021 22:03

Цитата:

Сообщение от рони (Сообщение 536417)
Vaska,
запрет ссылок кроме содержащих javascript.ru

javascript.ru поменял на sjavascript.ru.
sjavascript.ru - это уже сторонний домен, его скрипт должен запрещать, а он его пропускает. если этот домен вводить в той последовтельности действий, который я выше описал.

Vaska 10.05.2021 22:09

рони,
Этот баг легко отследить:
1. введите в чистую форму слово javascript.ru
2. нажмите кнопку Отправить
3. измените слово javascript.ru на sjavascript.ru
4. нажмите кнопку отправить
Скрипт не ругается на сторонний домен и отправляет сообщение.

рони 10.05.2021 22:13

Vaska,
пока нет вариантов у меня, скрипт делает то что в него заложено

рони 10.05.2021 22:32

Vaska,
extractDomain взято с просторов инета ...
<!DOCTYPE html>
<html>

<head>
    <title>Untitled</title>
    <meta charset="utf-8">
    <style type="text/css">
    </style>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.0/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-validate/1.19.2/jquery.validate.min.js"></script>
    <script>
        $(function() {
            $('a[dstype="consult_submit"]').click(function() {
                $('#save_consult_form2').submit();
            });

            function extractDomain(url) {
                let domain;
                //find & remove protocol (http, ftp, etc.) and get domain
                if (url.indexOf("://") > -1) {
                    domain = url.split('/')[2];
                } else {
                    domain = url.split('/')[0];
                }

                //find & remove www
                if (domain.indexOf("www.") > -1) {
                    domain = domain.split('www.')[1];
                }

                domain = domain.split(':')[0]; //find & remove port number
                domain = domain.split('?')[0]; //find & remove url params

                return domain;
            }


            $.validator.addMethod('removeLink', function(value, element) {
                    let reg = /(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|(www\.)?[a-zA-Z0-9]+\.[^\s]{2,})/mig
                    let match = value.match(reg);
                    return !match || match.every(link => extractDomain(link) == 'javascript.ru')
                },
                'Сообщение содержит запрещённые ссылки');
            $('#save_consult_form2').validate({
                errorPlacement: function(error, element) {
                    $('span[dstype="error_msg"]').append(error);
                },
                submitHandler: function(form) {
                    ds_ajaxpost('save_consult_form2');
                },
                onkeyup: false,
                rules: {
                    content: {
                        required: true,
                        maxlength: 200,
                        removeLink: true
                    }
                },
                messages: {
                    content: {
                        required: 'Вы не указали вопрос',
                        maxlength: 'Вопрос не должен превышать 200 символов.'
                    }
                }
            });
        });
    </script>
</head>

<body>
    <form method="post" id="save_consult_form2" action='goods/save_consult'>
        <div class="comment-add"><textarea id="textfield3" name="content" type="text" rows="10" cols="70">
         javascript.ru
         https://cdnjs.cloudflare.com/ajax   //для теста удалить эту строку
         https://www.javascript.ru
        </textarea></div>
        <div class="comment-act">
            <a href="JavaScript:void(0);" dstype="consult_submit" class="dss-btn">Отправить</a>
        </div>
        <span id="consultcharcount"></span> <span dstype="error_msg"></span>
    </form>
</body>

</html>

voraa 10.05.2021 23:32

А есть еще такие адреса сайтов
http://ргакфд.рф (там идет переадресация на http://rgakfd.ru/, но тем не менее адрес такой задать можно)
А еще
https://профессии.дети

Есть так же адреса с иероглифами, арабскими буквами .....

Vaska 11.05.2021 03:17

рони,
да, этот вариант хорошо работает.
Сейчас начал то же самое делать с номерами телефонов. Это оказалось тоже очень интересная тема. Вариантов написания много, нужно все учесть. Полного решения пока в интернете не нашел, хотя вижу, что люди ищут ответы на такие вопросы.
Странно, что такой файл скрипта ещё никто не создал как плагин, чтобы можно было настроить вырезку ссылок, телефонов, емейлов, html...
Может у вас есть вариант регулярного выражения, которое содержит все возможные варианты написания номера телефона на 10, 11, 12 цифр?
Я так понимаю, что сначала нужно из номера телефона удалить все символы: +, -, пробел, точка, различные скобки.
Далее полученные цифры 1234567890 распознавать как номер телефона по количеству числительных символов для 10, 11, 12 цифр.
Получается нужна последовательность действий в функции.

Vaska 11.05.2021 03:24

Цитата:

Сообщение от voraa (Сообщение 536427)
А есть еще такие адреса сайтов
http://ргакфд.рф (там идет переадресация на http://rgakfd.ru/, но тем не менее адрес такой задать можно)
А еще
https://профессии.дети

Есть так же адреса с иероглифами, арабскими буквами .....

"Штирлиц не был так близок к провалу, как в этот вечер..,"
Да, вышерасположенный скрипт не распознает домены отличные от латинского написания.
Я думаю тут нужен другой подход.
Нужно проверять слова с точкой и запрещать те слова, у которых точка находится слева без пробела, у всех буквенных символов написанных не на латинице.
Это видимо будет отдельная проверка на основе RegExp.

И кстати, регулярное выражение для PHP, в первом посту, тоже не распознает IDN-домены. Плохо.

voraa 11.05.2021 07:59

Смысл бы этого понять.
Защита от спама?
Ну просто режьте все, что начинается с http://, https://, www. и до ближайшего пробельного символа.
Но и перебдеть тоже не хорошо

Цитата:

Сообщение от Vaska
и запрещать те слова, у которых точка находится слева без пробела

Не вариант. Человек может просто забыть поставить пробел после точки в конце предложения.

От всего не защитишься. Если просто написать rgakfd.ru или ргакфд.рф или профессии.дети в адресной строке браузера, то он воспримет это как нормальный адрес. Если все такое резать, то мы просто будем резать невинные ошибки людей, типа "... важен выбор профессии.дети не всегда думают об этом...."
Где то в бдении нужно остановиться.

Лень проверять, а адреса с ip распознаются? Типа http://212.22.95.42/

Vaska 11.05.2021 14:11

Цитата:

Сообщение от voraa (Сообщение 536433)
Смысл бы этого понять.
Защита от спама?

Да, защита от спама.
Некоторые сайты даже нанимают людей для премодерации или нейросеть подключают.
Видят в спаме прямую угрозу.

Vaska 12.05.2021 11:44

Помогли ребята с хабра.
Регулярное выражение, которое видит домены с нелатинскими символами:
'/[^\P{L}a-z]+(\.[^\P{L}a-z]+)+/iu'

Проверено на трех типах доменов https://regex101.com/r/ME9Wwu/1
На сайте для PHP и для javascript хорошо работает, можно применять.

Vaska 07.07.2021 14:21

Приветствую!

решено.

Vaska 08.07.2021 08:41

Решено.


Часовой пояс GMT +3, время: 06:00.