Как проверить поле URL с помощью формы AJAX - PullRequest
0 голосов
/ 25 апреля 2019

Я создал простую форму ajax на основе этого учебника , и все работает хорошо. Единственная проблема, с которой я столкнулся, заключается в том, что я не могу понять, как проверять данные поля URL. Кажется, что даже если я установил тип поля как URL, он все равно обрабатывается, если это не URL.

Есть идеи?

example.html

<html>
<head>
<script>
function ajax_post(){
    // Create our XMLHttpRequest object
    var hr = new XMLHttpRequest();
    // Create some variables we need to send to our PHP file
    var url = "my_parse_file.php";
    var dlink = document.getElementById("dirtylink").value;
   var vars = "dlink="+dlink;
    hr.open("POST", url, true);
    // Set content type header information for sending url encoded variables in the request
    hr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    // Access the onreadystatechange event for the XMLHttpRequest object
    hr.onreadystatechange = function() {
	    if(hr.readyState == 4 && hr.status == 200) {
		    var return_data = hr.responseText;
			document.getElementById("status").innerHTML = return_data;
	    }
    }
    // Send the data to PHP now... and wait for response to update the status div
    hr.send(vars); // Actually execute the request
    document.getElementById("status").innerHTML = "processing...";
}
</script>
</head>
<body>
<h2>Ajax Post to PHP and Get Return Data</h2>
<input id="dlink" name="dlink" class="putfield" type="url" pattern="https?://.+" required name="website">
<input name="myBtn" type="submit" value="Submit Data" onclick="ajax_post();"> <br><br>
<div id="status"></div>
</body>
</html>

my_parse_file.php

<?php 
echo 'Thank you '. $_POST['firstname'] . ' ' . $_POST['lastname'] . ', says 
the PHP file';
?>

Ответы [ 2 ]

2 голосов
/ 25 апреля 2019

Эти теги недопустимы / стандартные теги HTML:

  • Тип = "URL"
  • шаблон = "https:? //.+"
  • обязательны для заполнения

Напишите ваш HTML-ввод, как это:

<input id="dlink" name="dlink" class="putfield" type="text" value="http://"/>

(ссылка или веб-сайт, который вы хотите назвать по имени!?)

Затем вы должны сначала тщательно проверить / проконтролировать все ваши входные данные на стороне сервера, поэтому в my_parse_file.php:

<?php
//unescape data if magic quotes is activated
function strip(&$str) {
    if(!is_array($str)) { $str = stripslashes($str); }
    }
if(get_magic_quotes_gpc() || get_magic_quotes_runtime()) {
    array_walk($_GET, 'strip');
    array_walk($_POST, 'strip');
    }

//init vars
if(isset($_POST['dlink'])) { $dlink = trim($_POST['dlink']); }else{ $dlink = ''; }

//tiny protect against code injection (XSS)
//maybe need to be revised, with eventual addslashes(), depanding on what you do with $dlink
$dlink = strip_tags($dlink);

//protect against multiline injection
if(preg_match('`^([^\r\n]*)`', $dlink, $match)) { $dlink = $match[1]; }

//control is a right url, can need a little improvement for the right domain format
if(!preg_match('`^(http[s]?://.+)`i', $dlink)) { echo "error"; exit(); }

echo 'Thank you! the url is '.$dlink.', says the PHP file';
?>

Затем вы можете добавить элемент управления JS на стороне клиента, чтобы быть более отзывчивым и избегать http-запроса, если плохой dlink:

var dlink = document.getElementById("dlink").value;
if(!dlink.match(/^http[s]?:\/\/.+/gi)) { alert("url not valid"); return 0; }
var vars = "dlink="+dlink;

Будьте осторожны с вашим прямым эхом $ _POST ['varname'], которые не являются ненадежно.

Кажется, что filter_var () тоже может выполнять работу по управлению URL, как сказал Сильвио.


--- ОБНОВЛЕНИЕ ---

Рядом с моим ответом я хотел сделать какую-то альтернативу filter_var () вручную и найти самый простой способ защитить $ _POST и $ _GET "echo" от внедрения.

Я не очень одобряю, как filter_var () проверяет / дезинфицирует URL-адрес, потому что зачем мне записывать / выбирать в моей базе данных URL-адрес, содержащий инъекцию типа "domain.com<script>alert(cookie)</script>" или даже отображать для клиента "this url is domain.comalert(cookie) ».

Итак, вот что я сделал:

function safe_char($str) {
    $buf = '';
    $enable = array(
        9 => 1,//\t
        10 => 1,//\n
        13 => 1//\r
        );
    $len = mb_strlen($str);
    $i = 0;
    while($i < $len) {
        $ascii = ord($str[$i]);
        //remove unwelcome char, about decimal 0-31 and 127, keep only \t \r \n
        if($ascii !== 127/*DEL*/ && ($ascii > 31 || isset($enable[$ascii]))) {
            $buf .= $str[$i];
            }
        $i++;
        }
    return $buf;
    }

function safe_strip_tags($str, $remove_hack=false, $log_hack=false) {
    if($remove_hack) {
        //$str_ini = $str;

        //remove tag content only when tags script/noscript detected
        $str = preg_replace('`<[[:space:]]*(script|noscript)[^>]*>(.*?<[[:space:]]*/\1[[:space:]]*>|.+)`is', '', $str);

        //logs hack
        //if($log_hack && $str !== $str_ini) {
        //  logs(array('try injection', $str_ini));
        //  }
        }
    //safe delete tags
    $str = strip_tags($str);
    //delete the last unique > or <
    $str = preg_replace('`[<>]+`s', '', $str);
    return $str;
    }

function safe_write($str) {
    //replace by the html entities the critical char that cause injection works
    $char = array('&', '<', '>', '"', '\'');
    $replace = array('&amp;', '&lt;', '&gt;', '&quot;', '&apos;');
    return str_replace($char, $replace, $str);
    }

function filter_url($str, &$url=false, $strict=false) {
    $err = true;
    $str = trim($str);

    //remove unwelcome control char (about from x00 to x1F), it keep only \t \r \n
    $str = safe_char($str);

    //remove html tag and protect against injection (XSS)
    $url = safe_strip_tags($str, true, true);

    //protect against multiline injection
    if(preg_match('`^([^\r\n]*)`', $url, $match)) { $url = $match[1]; }

    //test is like an url
    if(!preg_match('`^(http|ftp)[s]?://.+`i', $url)) {
        //and reject other scheme
        if($url !== '' && mb_strpos($url, '://') === false) {
            //maybe case "www.url.com" so try add an http scheme
            $url = 'http://'.$url;
            $err = false;
            }
        }
    else{ $err = false; }

    //going to confirm url have valid domain
    if(!$err) {
        //remove char that we dont want in an url
        $url = preg_replace('`[\t]+`', '', $url);

        $host = parse_url($url, PHP_URL_HOST);
        if($host != null) {
            //no special char in domain name
            if(!preg_match('`^[a-z0-9._-]+$`i', $host)) { $err = true; }

            //no double dot in domain name
            if(!$err && mb_strpos($host, '..') !== false) { $err = true; }

            //domain name
            if(!$err && !preg_match('`[a-z0-9_-]{1,63}\.[a-z.]{2,10}$`i', $host)) { $err = true; }

            //local dev for http://localhost
            //if($err && preg_match('`^[a-z0-9_-]{1,63}$`i', $host)) { $err = false; }

            //more strict controls
            if(!$err) {
                $xpl = explode('.', $host);
                foreach($xpl as $v) {
                    //label not more long than 63 char
                    if(mb_strlen($v) > 63) { $err = true; break; }
                    //label must start with a letter
                    //if(preg_match('`^[0-9]+`', $v)) { $err = true; break; }
                    //label with underscore is normally not valid
                    //if(mb_strpos($v, '_') !== false) { $err = true; break; }
                    }
                }

            //ip
            if($err && preg_match('`^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$`', $host)) { $err = false; }
            //its enough, and not so restricted for the future, if you really want to ctrl an url, you have to request it
            }

        //bad host
        else{ $err = true; }
        }

    //url have been modified
    if($strict && $str !== $url) {
        $err = true;
        }

    if($err) { $url = false; }
    else{ return true; }
    return false;
    }

function filter_string($str, &$string=false, $strict=false) {
    $str = trim($str);
    $string = safe_char($str);//filter_var() cannot do that, so no php_filter_string()
    //string have been modified
    if($strict && $str !== $string) {
        return false;
        }
    return true;
    }

Пожалуйста, поделитесь с нами, если вы нашли инъекцию / ошибку или оптимизировали ее ...

Проверка результатов самодельного filter_url ():

//i writted the result from filter_url() in each comment
$arr = array(
    'https://url.com',//https://url.com
    'http://url.com',//http://url.com
    'http://url.com/test',//http://url.com/test
    'http://url.com/test.php?param=a\'b \"c*&plus=1',//http://url.com/test.php?param=a'b \"c*&plus=1
    'http://url.com/\'t"e*s t',//http://url.com/'t"e*s t
    'http://urlcom',//FALSE
    'http://urlcom/url.com',//FALSE
    'http://url.com\test',//FALSE
    'http://url.com\'"*',//FALSE
    'http://url.c\'"*',//FALSE
    'http://url.\'"*',//FALSE
    '',//FALSE
    'u',//FALSE
    'u.co',//http://u.co
    'http://',//FALSE
    'http://u',//FALSE
    'http://u.c',//FALSE
    'http://u.co',//http://u.co
    'http://ur.co',//http://ur.co
    'http://www.url.com',//http://www.url.com
    'http://www.url',//http://www.url
    'http://url_url.com',//http://url_url.com
    'http://www.thislabelistoolongthislabelistoolongthislabelistoolongthislabelistoolong.com',//FALSE
    'http://localhost',//FALSE
    'http://4url.com',//http://4url.com
    'http://sub.sub.url.com',//http://sub.sub.url.com
    'http://l.s.s.url.com',//http://l.s.s.url.com
    'http://127.0.0.1',//http://127.0.0.1
    'http://127.0.0.1.2',//FALSE
    'http://127.0.0',//FALSE
    'http://127.0.0.1/filter/',//http://127.0.0.1/filter/
    'http://127.0.0.url',//http://127.0.0.url
    'http://127.url',//http://127.url
    'http://url.127',//FALSE
    'http://u27.c27',//FALSE
    'http://u27.com',//http://u27.com
    'http://127.0.0.1:80/filter/',//http://127.0.0.1:80/filter/
    'http://127.0.0.1.2:80/filter/',//FALSE
    'http://1278.0.0.1.2:80/filter/',//FALSE
    'ftps://127.0.0.1:80/filter/',//ftps://127.0.0.1:80/filter/
    'ftp://url.com',//ftp://url.com
    'javascript://comment%0Aalert(1)',//FALSE
    'javascript://url.com',//FALSE
    'www.url.com',//http://www.url.com
    'http://url..com',//FALSE
    'http://url.com..com',//FALSE
    'http://url.com/te..st',//http://url.com/te..st
    'http://url.com/test?param=%0D%0A%61%62',//http://url.com/test?param=%0D%0A%61%62
    'http://url.com/'."\r\n".'multiline',//http://url.com/
    'http://url.com/'."\n".'multiline',//http://url.com/
    'http://url.com/xy; >>',//http://url.com/xy; 
    'http://url.com/two>text',//http://url.com/text
    'http://url.com/two>text',//http://url.com/text
    'http://url.com/">alert(cookie)',//http://url.com/"
    'http://url.com/%0D%0Aalert(cookie)',//http://url.com/%0D%0A
    'http://url.com/%0D%0Aalert(cookie)path/',//http://url.com/%0D%0A
    'http://url.com/txt',//http://url.com/txt
    'http://url.com/<   space   >text',//http://url.com/spacetext
    'http://url.com/txt',//http://url.com/txt
    'http://url.com/%3Ctag%3Cone%3Etwo%3Etext%3Cthree%3E',//http://url.com/%3Ctag%3Cone%3Etwo%3Etext%3Cthree%3E
    'http://url.com/%0D%0A%3Cscript%3Ealert(cookie)%3C/script%3E',//http://url.com/%0D%0A%3Cscript%3Ealert(cookie)%3C/script%3E
    'http://url.com/canbenice%0D%0A%3C%73%63%72%69%70%74%3E%61%6C%65%72%74%28%63%6F%6F%6B%69%65%29%3C%2F%73%63%72%69%70%74%3E',//http://url.com/canbenice%0D%0A%3C%73%63%72%69%70%74%3E%61%6C%65%72%74%28%63%6F%6F%6B%69%65%29%3C%2F%73%63%72%69%70%74%3E
    //'http://url.co�m/charctrl',//http://url.com/charctrl
    );
$charctrl = '';
$i = 0;
while($i < 32) {
    if($i!==9 && $i!==10 && $i!==13) {
        $charctrl .= chr($i);
        }
    $i++;
    }
$charctrl .= chr(127);
$arr[] = 'http://url.co'.$charctrl.'m/charctrl';

echo '';
foreach($arr as $v) {
    echo $v.' => ';
    if(filter_url($v, $url)) { echo $url; }else{ echo 'FALSE'; }
    echo "\r\n";
    }
echo '
'; echo "\ r \ n \ r \ n". '

'. "\ r \ n \ r \ n"; echo '
';
foreach($arr as $v) {
    echo $v.' => ';
    if(php_filter_url($v, $url)) { echo $url; }else{ echo 'FALSE'; }
    echo "\r\n";
    }
echo '
';

filter_var () решение: Извините за отсутствие у меня этих функций filter_var () ... У этой функции есть немного неоднозначное имя, но, наконец, она безопасна при правильном использовании, поэтому будьте осторожны, выбирая правильный идентификатор / флаг.

  • FILTER_VALIDATE_URL не предназначен для защиты вас от инъекций, он просто контролирует, может ли это быть URL.
  • FILTER_SANITIZE_STRING необходимо применять для защиты от XSS при отображении переменной.
function php_filter_url($str, &$url=false, $strict=false) {
    $err = true;
    $str = trim($str);
    $url = $str;

    //protect against multiline injection
    if(preg_match('`^([^\r\n]*)`', $url, $match)) { $url = $match[1]; }

    //add this because FILTER_VALIDATE_URL accept others scheme
    if(!preg_match('`^(http|ftp)[s]?://.+`i', $url)) {
        //reject other scheme
        if($url !== '' && mb_strpos($url, '://') === false) {
            //maybe case "www.url.com" so try add an http scheme
            $url = 'http://'.$url;
            $err = false;
            }
        }
    else{ $err = false; }

    if(!$err) {
        $url = filter_var($url, FILTER_VALIDATE_URL, FILTER_FLAG_SCHEME_REQUIRED | FILTER_FLAG_HOST_REQUIRED);
        if(!$url) { $err = true; }
        }

    if(!$err) {
        $url = filter_var($url, FILTER_SANITIZE_STRING, FILTER_FLAG_NO_ENCODE_QUOTES);
        if(!$url) { $err = true; }
        }

    //url have been modified
    if($strict && $str !== $url) {
        $err = true;
        }

    if($err) { $url = false; }
    else{ return true; }
    return false;
    }

Я упоминаю, что прошу прощения за мои "экзотические" отступы, мне вообще не нравятся "официальные", пытались вернуться, но невозможно ... поэтому я могу понять, что вы думаете о моем: D

Результаты теста filter_var (), псевдоним php_filter_url (): Я позволю себе попробовать URL-адреса самостоятельно, есть некоторые «ложные» совпадения, но они выглядят не так плохо, за исключением, может быть, следующих результатов:

Скамья: filter_url () примерно в 5 раз медленнее, чем php_filter_url (), и мы можем не оптимизировать больше без потери легко читаемого скрипта. Но это не драматическая скамейка проиграть. (PHP 5.4)

Лучшее решение: Используйте самодельное решение, если вам нужно обработать случай, когда filter_var () не может. Наконец, URL, даже хорошо написанный и проверенный, может быть плохим URL ... вы должны запросить его, чтобы действительно знать. И когда кто-то пытается внедрить что-то, я сомневаюсь, что это с правдивой информацией, так что эти «url.comalert (cookie)», наконец, бесполезны, домашняя версия пытается очистить это, чтобы освободить место, и может записать информацию о внедрении в журналы. Хм, я просто думаю, что, возможно, нам не нужно проверять переменные, где обнаружена инъекция ...

О форме: По причине того, что проверять входные данные в javascript (на стороне клиента) небезопасно, вы должны обработать возможную ошибку, возвращаемую php, чтобы быть уверенным, что делать дальше, в javascript.

Ваш пример кода плохо приспособлен к этой ситуации, потому что обычно вам нужно использовать ответ xml вместо фактического текстового ответа, чтобы правильно проверить «в искусстве xhtml» информацию в javascript. (и для этого нужно гораздо больше кода / понимания)

Итак, чтобы оставаться простым, но очень правильным, вы можете выбрать альтернативу, подобную этой:

<html>
<head>
<style type="text/css">
.field {
    font-weight:bolder;
    border:2px gray solid;
    color:black;
    }
.fieldError {
    border:2px red solid;
    color:red;
    }
</style>

<script type="text/javascript">
function getXhr() {
    var xhr = false;
    try{
    xhr = new XMLHttpRequest();
    }catch (e){
        try{
        xhr = new XDomainRequest();
        }catch (e){
            try{
            xhr = new ActiveXObject('Msxml2.XMLHTTP');
            }catch (e){
                try{
                xhr = new ActiveXObject('Microsoft.XMLHTTP');
                }catch (e){
                    alert('Your browser is not compatible with XML request');                           
                    }
                }
            }
        }
    return xhr;
    }

function encodeUrl(str) {
    if(encodeURIComponent) { str = encodeURIComponent(str); }
    else if(escape) { str = escape(str); }
    //sure not any = and &
    str = str.replace(/=/gi, "%3D");
    str = str.replace(/&/gi, "%26");
    return str;
    }

function getNodeText(tag, content) {
    var regex = new RegExp('<'+tag+'>(.*?)</'+tag+'>', 'g');
    var match = regex.exec(content);
    return match[1];
    }

function safeWrite(str) {
    str = str.replace(/</g, '&lt;');
    str = str.replace(/>/g, '&gt;');
    str = str.replace(/\"/g, '&quot;');
    str = str.replace(/\'/g, '&apos;');
    return str;
    }

function ajaxPost() {
    var err = false;
    var errMsg = 'Invalid form';

    //init obj
    var dlink = document.getElementById("dlink");
    var firstname = document.getElementById("firstname");

    //reinit input class
    dlink.className = "field";
    firstname.className = "field";

    //test input dlink
    if(!dlink.value.match(/^http[s]?:\/\/.+/gi)) {
        dlink.className = "field fieldError";
        err = true;
        }
    //test input firstname
    if(firstname.value == '') {
        firstname.className = "field fieldError";
        err = true;
        }
    //return directly on error
    if(err) {
        document.getElementById("status").innerHTML = errMsg;
        return false;
        }

    //create our XMLHttpRequest object
    var xhr = getXhr();
    //create some variables we need to send to our PHP file
    var url = "my_parse_file.php";
    var param = "dlink="+encodeUrl(dlink.value)+"&firstname="+encodeUrl(firstname.value);
    xhr.open("POST", url, true);
    //set content type header information for sending url encoded variables in the request
    xhr.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
    //access the onreadystatechange event for the XMLHttpRequest object
    xhr.onreadystatechange = function() {
        if(xhr.readyState == 4 && xhr.status == 200) {
            //alert(xhr.responseText);

            //make our own tiny parser, and get all the response infos
            var dlinkText = getNodeText("dlink", xhr.responseText);
            var dlinkErr = getNodeText("dlinkErr", xhr.responseText);
            var firstnameText = getNodeText("firstname", xhr.responseText);
            var firstnameErr = getNodeText("firstnameErr", xhr.responseText);

            //update var for a more secure/easy int type handle
            dlinkErr = parseInt(dlinkErr, 10);
            firstnameErr = parseInt(firstnameErr, 10);

            //handle the real error returned by php
            if(dlinkErr !== 0) {
                dlink.className = "field fieldError";
                err = true;
                }
            if(firstnameErr !== 0) {
                firstname.className = "field fieldError";
                err = true;
                }

            //form fail
            if(err) { document.getElementById("status").innerHTML = errMsg; }

            //form pass all the test, we recontrol with safeWrite() that there is no code injection
            else{
                var success = 'Thank you '+safeWrite(firstnameText)+'! the url is '+safeWrite(dlinkText);
                document.getElementById("status").innerHTML = success;
                }
            }
        }
    //send the data to PHP now... and wait for response to update the status div
    xhr.send(param);//actually execute the request
    document.getElementById("status").innerHTML = "processing...";
    }
</script>
</head>
<body>
<h2>Ajax Post to PHP and Get Return Data</h2>
<label for="dlink">dlink :</label><input id="dlink" name="dlink" type="text" value="http://" class="field"/><br/>
<label for="firstname">firstname :</label><input id="firstname" name="firstname" type="text" value="" class="field"/><br/>
<input id="submit" name="submit" type="submit" value="Submit Data" onmouseup="ajaxPost();">
<div id="status"></div>
</body>
</html>

my_parse_file.php

<?php
//force to refresh the cache of the browser
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
header('Last-Modified: '.gmdate('D, d M Y H:i:s').' GMT');
header('Cache-Control: no-store, no-cache, must-revalidate');
header('Cache-Control: post-check=0, pre-check=0', false);
header('Pragma: no-cache');

//include our filter functions
include './filter.php';

//init vars
$output = '';
$dlink_err = 0;
$firstname_err = 0;

//control $_POST
if(!isset($_POST['dlink'])) { $_POST['dlink'] = ''; $dlink_err = 1; }//trim is done inside filter functions
if(!isset($_POST['firstname'])) { $_POST['firstname'] = ''; $firstname_err = 1; }

//control/validate dlink is like a valid url, and clean the code injection try
if(!filter_url($_POST['dlink'], $dlink)) { $dlink_err = 1; }
//if(!php_filter_url($_POST['dlink'], $dlink)) { $dlink_err = 1; }//not well cleaned

//control firstname, only remove unwelcome charaters from the string, it can return false only if you use the $strict arg
if(!filter_string($_POST['firstname'], $firstname)) { $firstname_err = 1; }

//validate firstname is not empty
if($firstname === '') { $firstname_err = 1; }

//prepare the response, and protect against injection (XSS) with the help of safe_write()
$output .= '<dlink>'.safe_write($dlink).'</dlink>
<dlinkErr>'.$dlink_err.'</dlinkErr>
<firstname>'.safe_write($firstname).'</firstname>
<firstnameErr>'.$firstname_err.'</firstnameErr>';

echo $output;
?>

Мое первое замечание о «недействительном / нестандартном HTML-теге» немного неясно, это действительный атрибут новых тегов из HTML5 этой даты с 2015 года, но если вы его используете, ваш сайт будет несовместим со «старым» клиентомчто нет поддержки этого "нового" HTML5.Таким образом, чтобы создать веб-сайт, который, несомненно, совместим во всем мире, вы должны использовать HTML4, а точнее XHTML 1.0, датируемый 2000 годом.

Есть еще одна вещь, которая не очень хороша в этом коде:Форма не является функциональной, если JavaScript отключен.Как правило, правильный способ создания веб-сайта - это заставить его работать без javascript (по крайней мере, основных функций внешнего интерфейса), и только после этого вы добавляете слой javascript.

Так что, на мой взгляд, вы должны взять путь внаоборот, поэтому я предлагаю вам перезапустить, сначала создав простую форму php + проверку, и только потом вы добавляете слой js.

Советы по предотвращению записи двойной проверки состоят в том, чтобы повторно использовать одну и ту же проверку php-файла в двух местах, 1-й в заголовке простой php-формы и 2-й в запросе ajax (поэтому этот файл проверки называется my_parse_file.php в нашем примере, но его нужно изменить, чтобы справиться с тем, кто писал).Я не пишу это решение, потому что оно на самом деле не отвечает на заданный вопрос об использовании ajax, и мы уже находимся на границе ...: D

Сообщение в бутылке на SOa: «Совместимая всемирная паутина» - это все равно, что серьезно умирать в эти времена, поэтому, пожалуйста, сделайте так, чтобы она выжила, создавая совместимые веб-сайты:)

1 голос
/ 25 апреля 2019

Вы можете использовать метод filter_var с флагом FILTER_VALIDATE_URL, например:

var_dump(filter_var($_POST['dlink'], FILTER_VALIDATE_URL, FILTER_FLAG_SCHEME_REQUIRED));

Необязательный флаг FILTER_FLAG_SCHEME_REQUIRED предназначен для проверки ввода с http / https

Еще одно примечаниео вашем коде: в поле ввода URL есть 2 атрибута name.

Итак, вы можете установить $dlink var, используя filter_input метод следующим образом:

$dlink = filter_input(INPUT_POST, 'dlink', FILTER_VALIDATE_URL, FILTER_FLAG_SCHEME_REQUIRED);
...