如何在文本框中验证客户端的 youtube url

Posted

技术标签:

【中文标题】如何在文本框中验证客户端的 youtube url【英文标题】:How to validate youtube url in client side in text box 【发布时间】:2015-04-28 10:00:49 【问题描述】:

我必须创建一个文本框,它只允许您管视频的网址。

为了处理服务器端的验证,我使用below code

$rx = '~
    ^(?:https?://)?              # Optional protocol
     (?:www\.)?                  # Optional subdomain
     (?:youtube\.com|youtu\.be)  # Mandatory domain name
     /watch\?v=([^&]+)           # URI with video id as capture group 1
     ~x';

$has_match = preg_match($rx, $url, $matches);

我一直在为客户端验证寻找相同的解决方案。我发现了 <input type="url"> here 但它似乎只适用于 html5 浏览器。

是否可以使用文本框进行客户端验证,以便与所有浏览器兼容?

谢谢

【问题讨论】:

Hitesh,如果有人为你工作,你应该标记为三个答案中的任何一个,以便其他人可以信任。 很难选择哪一个是正确的!!! @innomanik 和您的答案似乎都按我的预期工作。给我一些时间,我会接受正确的答案。 【参考方案1】:

转义正则表达式中存在的所有正斜杠,然后将修改后的正则表达式放在 / 分隔符中,不带任何空格或注释行,您不需要添加 x 修饰符。

var re = /^(?:https?:\/\/)?(?:www\.)?(?:youtube\.com|youtu\.be)\/watch\?v=([^&]+)/m;

【讨论】:

【参考方案2】:

这是验证 youtube url 的代码-

function validateYouTubeUrl()

    var url = $('#youTubeUrl').val();
        if (url != undefined || url != '') 
            var regExp = /^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=|\?v=)([^#\&\?]*).*/;
            var match = url.match(regExp);
            if (match && match[2].length == 11) 
                // Do anything for being valid
                // if need to change the url to embed url then use below line
                $('#ytplayerSide').attr('src', 'https://www.youtube.com/embed/' + match[2] + '?autoplay=0');
            
            else 
                // Do anything for not being valid
            
        

小提琴网址: https://jsfiddle.net/cpjushnn/12/

【讨论】:

哇!您甚至添加了如何更改 url 以嵌入 url ...如果可能,请提供 jsfiddle。谢谢 @hitesh,刚刚也添加了小提琴网址,尝试一下并标记为答案,如果是这样的话...... if (match && match[2].length == 11) ...这背后的逻辑我不明白...你能解释一下...谢谢 @Prateek,这意味着该部分应匹配列表中不存在的单个字符,即 #、& 和 ?因为这些字符在 URL 中具有特殊含义/用途。你可以在这里玩更多 - regex101.com/r/pN5hU5/1 简洁版:/^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|&v=|\?v=)([^#&?]*).*/【参考方案3】:

查看这个工作示例:

function matchYoutubeUrl(url) 
    var p = /^(?:https?:\/\/)?(?:m\.|www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-)11)(?:\S+)?$/;
    if(url.match(p))
        return url.match(p)[1];
    
    return false;

更新小提琴:http://jsfiddle.net/3ouq9u3v/13/

【讨论】:

它按预期工作,我很高兴你添加了工作链接.. 非常感谢 感谢分享 RegExp 属性已被弃用的信息,但我很惊讶微软为什么没有提到这一点。我现在更新了我的解决方案。【参考方案4】:

结合这里的答案和一些修改,我想出了这个正则表达式:

^(?:https?:\/\/)?(?:m\.|www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-)11)(\?\S*)?$

这将匹配任何格式,但如果 id 长度超过 11 个字符,则会不匹配。还可以使用“?”添加开始视频标签最后的部分。

你可以通过粘贴into this来测试它

【讨论】:

【参考方案5】:

再次更新。在我看来,到目前为止,我已经确定了 6 种情况可以满足(我编造了这些名称):

普通网址

    https://www.youtube.com/watch?v=12345678901

分享网址

    https://youtu.be/12345678901

分享网址与开始时间

    https://youtu.be/12345678901?t=6

手机浏览器网址

    https://m.youtube.com/watch?v=12345678901&list=RD12345678901&start_radio=1

长网址

    https://www.youtube.com/watch?v=12345678901&list=RD12345678901&start_radio=1&rv=smKgVuS

带有开始时间的长网址

    https://www.youtube.com/watch?v=12345678901&list=RD12345678901&start_radio=1&rv=12345678901&t=38

我最初根据 Jitendras 的答案提供了一个扩展的答案,因为这似乎有一些差距。例如,如果您在末尾添加字符,则使用较短的共享 URL(例如 https://youtu.be/abcdefgh_ij),Jitendras 没有捕捉到它。此外,如果用户在已经存在错误的情况下删除了文本字段中的值,则不会将其删除。

但是,我假设原始发帖人实际上想在 iframe 嵌入中使用 URL,而这里的答案都不适用于此。嵌入的url格式不同,需要处理。

以下是我正在执行的操作,以获取用户输入、对其进行验证、将其替换为格式正确的可嵌入 url,然后将其分配给 iframe 以在 UI 上显示。

可能对某人有好处....

    function validateVideoLink() 
        var UserInputField = document.getElementById("UserInputField");
        var InputFieldText = UserInputField.value;
        var FieldValidationPara = document.getElementById("FieldValidationPara");
        
        if ((InputFieldText.includes("watch?v=") || InputFieldText.includes("https://m.youtube") || InputFieldText.includes("watch?app=desktop&v=")) && !InputFieldText == "") 
            var endOfString = InputFieldText.split(/=(.*)/)[1];
            var stringLength = endOfString.length;
        
            var p = /^(?:https?:\/\/)?(?:m\.|www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-)11)(?:\S+)?$/;
            if (!InputFieldText.match(p)) 
                FieldValidationPara.style.display = 'block';
                document.getElementById('CardDynamicVideo').src = '';
             else 
                FieldValidationPara.style.display = 'none';
                var processedUrl = processVideoUrl(InputFieldText, true);
                document.getElementById('CardDynamicVideo').src = processedUrl;
                $("#UserInputField").val(processedUrl);
            
        
            if (stringLength > 11) 
                FieldValidationPara.style.display = 'block';
                document.getElementById('CardDynamicVideo').src = '';
            

         else if (InputFieldText.includes("embed") && !InputFieldText== "") 

        //This else if block is needed in case the user adds extra characters on the end of the correctly processed embed url.

            var endOfString = InputFieldText.split('/')[4];
            var stringLength = endOfString.length;
            console.log('StringLength: ' + stringLength);
    
            var p = /^(?:https?:\/\/)?(?:m\.|www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-)11)(?:\S+)?$/;
            if (!InputFieldText.match(p)) 
                FieldValidationPara.style.display = 'block';
                document.getElementById('CardDynamicVideo').src = '';
             else 
                FieldValidationPara.style.display = 'none';
                var processedUrl = processVideoUrl(InputFieldText, true);
                document.getElementById('CardDynamicVideo').src = processedUrl;
                $("#UserInputField").val(processedUrl);
            
    
            if (stringLength > 11) 
                FieldValidationPara.style.display = 'block';
                document.getElementById('CardDynamicVideo').src = '';

        else if (InputFieldText.includes("tu.be") && !InputFieldText == "") 

            var endOfString = InputFieldText.split('/')[3];
            var stringLength = endOfString.length;
        
            var p = /^(?:https?:\/\/)?(?:m\.|www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-)11)(?:\S+)?$/;
            if (!InputFieldText.match(p)) 
                FieldValidationPara.style.display = 'block';
                document.getElementById('CardDynamicVideo').src = '';
             else 
                FieldValidationPara.style.display = 'none';
                document.getElementById('CardDynamicVideo').src = VideoLinkText;
                var processedUrl = processVideoUrl(InputFieldText, false);
                document.getElementById('CardDynamicVideo').src = processedUrl;
                $("#UserInputField").val(processedUrl);
            
        
            if (stringLength > 11) 
                FieldValidationPara.style.display = 'block';
            document.getElementById('CardDynamicVideo').src = '';
            

       else 

            var p = /^(?:https?:\/\/)?(?:m\.|www\.)?(?:youtu\.be\/|youtube\.com\/(?:embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-)11)(?:\S+)?$/;
            if (!InputFieldText.match(p) && !InputFieldText == "") 
                FieldValidationPara.style.display = 'block';
            document.getElementById('CardDynamicVideo').src = '';
             else 
                FieldValidationPara.style.display = 'none';
            document.getElementById('CardDynamicVideo').src = InputFieldText;
            
        
    
    
function processVideoUrl(rawUrl, fullUrl) 

    if (fullUrl) 
        var processed = rawUrl.replace('watch?v=', 'embed/')
        if (processed.includes("https://m.youtube")) 
            processed = rawUrl.replace('m.youtube', 'www.youtube');
            if (processed.includes("&list=")) 
                processed = processed.split('&list=')[0];
                return processed;
                console.log('Processed 1: ' + processed);
            
         else if (processed.includes("watch?app=desktop&v=")) 
            processed = rawUrl.replace('watch?app=desktop&v=', 'embed/');
            if (processed.includes("&list=")) 
                processed = processed.split('&list=')[0];
                return processed;
                console.log('Processed 1: ' + processed);
            
         else if (processed.includes("&list=")) 
            processed = processed.split('&list=')[0];
            return processed;
            console.log('Processed 1: ' + processed);
        
        console.log('Processed 2: ' + processed);
        return processed;
     else 
        var processed = rawUrl.replace('https://youtu.be/', 'https://www.youtube.com/embed/')
        if (processed.includes("?t=")) 
            processed = processed.split('?t=')[0];
            return processed;
        

        console.log('Processed 3: ' + processed);
        return processed;
    

以及对应的HTML:

<iframe class="embed-responsive-item" src="" id="CardDynamicVideo" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>

<div class="row">
    <input asp-for="YouTubeLink" class="form-control" id="UserInputField" onkeypress="validateVideoLink()" onkeyup="validateVideoLink()">
</div>
<div class="row">
    <p class="font-danger hide" id="FieldValidationPara">That is not a valid YouTube Link</p>
</div>

注意 1:仍有一些边缘情况需要解决。例如,如果您输入一些奇怪的 watch?v= 或 tu.be 组合,它还不会处理它们。但我认为以上内容作为一个起点已经足够扎实了。

注意 2:请注意您用于测试的视频。 YouTube 不允许嵌入带有受版权保护的背景音乐的视频,它们将显示为不可用。

【讨论】:

以上是关于如何在文本框中验证客户端的 youtube url的主要内容,如果未能解决你的问题,请参考以下文章

[译]为何我们需要同时拥有客户端和服务器端的验证手续

web服务端给手机客户端发送一条短信验证码,因为要跟客户端提交的比较,服务端怎么先保存这个验证码呢

如何从html中的文本框中清除搜索输入? [复制]

如何获取HTML中用户输入到文本框中的内容?

从令牌服务器(身份服务器 4)进行身份验证后重定向到客户端的相同 URL

如何在文本框中验证邮政编码并将相应的州/城市输出与其各自的标签相对应