尝试使用 JavaScript 验证 URL

Posted

技术标签:

【中文标题】尝试使用 JavaScript 验证 URL【英文标题】:Trying to Validate URL Using JavaScript 【发布时间】:2010-11-21 04:35:55 【问题描述】:

我想验证 URL 并显示消息。以下是我的代码:

$("#pageUrl").keydown(function()
        $(".status").show();
        var url = $("#pageUrl").val();

        if(isValidURL(url))

        $.ajax(
            type: "POST",
            url: "demo.php",
            data: "pageUrl="+ url,
            success: function(msg)
                if(msg == 1 )
                    $(".status").html('<img src="images/success.gif"/><span><strong>SiteID:</strong>12345678901234456</span>');
                else
                    $(".status").html('<img src="images/failure.gif"/>');
                
            
            );

            else

                    $(".status").html('<img src="images/failure.gif"/>');
            

    );


function isValidURL(url)
    var RegExp = /(ftp|http|https):\/\/(\w+:0,1\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?/;

    if(RegExp.test(url))
        return true;
    else
        return false;
    
 

我的问题是,即使输入正确的 URL 直到匹配正则表达式,它也会显示错误消息,即使 URL 类似于 "http://wwww",它也会返回 true。

感谢您的建议。

【问题讨论】:

不要忘记添加服务器端检查,因为 javascript 检查很容易被黑客入侵。 应该相对容易找到更可靠的正则表达式进行 URL 匹配(在 javascript 中)。在旁注中,我建议不要大写变量(例如您的示例中的RegExp),除非它们是构造函数/命名空间(您的变量不是)。也不要忘记 RegExp#test 已经返回布尔值所以你真的不需要 if/else;只是做 - return re.test(url). 注意:网址为“www”;是一个有效的网址。你可以有一个名为 wwww 的主机 Jquery 插件验证也验证 URL。 docs.jquery.com/Plugins/Validation/Methods/url Google 的 Closure 库在 goog.string.linkify 命名空间中有一个 URL 验证器,您可以在此处从源代码中删除它:code.google.com/p/closure-library/source/browse/closure/goog/… 查看 findFirstUrl() 【参考方案1】:

有人提到了 Jquery Validation 插件,如果你只是想验证 url,似乎有点过头了,这是插件中的 regex 行:

return this.optional(element) || /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]2)|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]2)|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]2)|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]2)|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]2)|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(value);

这是他们的来源:http://projects.scottsplayground.com/iri/

@nhahtdh 指出这已更新为:

        // Copyright (c) 2010-2013 Diego Perini, MIT licensed
        // https://gist.github.com/dperini/729294
        // see also https://mathiasbynens.be/demo/url-regex
        // modified to allow protocol-relative URLs
        return this.optional( element ) || /^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d1,3)3)(?!(?:169\.254|192\.168)(?:\.\d1,3)2)(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d1,3)2)(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d1,2|2[0-4]\d|25[0-5]))2(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]2,)).?)(?::\d2,5)?(?:[/?#]\S*)?$/i.test( value );

来源:https://github.com/jzaefferer/jquery-validation/blob/c1db10a34c0847c28a5bd30e3ee1117e137ca834/src/core.js#L1349

【讨论】:

jQuery Validation 的方法允许在域名中使用下划线(“_”)。据我发现,它不允许在域名中使用。只允许使用连字符(“-”)。例如,PHP 的 filter_var($url, FILTER_VALIDATE_URL) 似乎不允许在域名中使用下划线。 \u00A0-\uD7FF 范围过于宽泛。像 ” (\u201D) 这样的引号字符在该范围内。例如,如果首先在空格上拆分,则引用句子的结尾可能是“this”。如果这在技术上不是误报,那么在实践中通常会使用此正则表达式来识别 url。 上面的正则表达式已经替换为 jQuery Validation 源码中 Diego Perini 的正则表达式:github.com/jzaefferer/jquery-validation/blob/master/src/… 正则表达式已移至第 1306 行 - github.com/jzaefferer/jquery-validation/blob/master/src/… @Kousha: www.google.com 不是一个有效的 URL,所以它应该没有通过测试。【参考方案2】:

我在 google 中检查了很多 url 验证器,但没有人为我工作。例如,我希望在“aa.com”之类的链接上看到有效。我喜欢傻傻地检查字符串中的点号。

function isValidUri(str) 
  var dotIndex = str.indexOf('.');
  return (dotIndex > 0 && dotIndex < str.length - 2);

它不应该停留在字符串的开头和结尾(目前我们没有一个字符的***域名)。

【讨论】:

【参考方案3】:

在类似的情况下,我侥幸逃脱:

someUtils.validateURL = function(url) 
    var parser = document.createElement('a');
    try 
        parser.href = url;
        return !!parser.hostname;
     catch (e) 
        return false;
    
;

即如果浏览器可以为你做这件事,为什么还要发明***?但是,当然,这只适用于浏览器。

解析后的 URL 有不同的部分,浏览器会如何解释它:

parser.protocol; // => "http:"
parser.hostname; // => "example.com"
parser.port;     // => "8080"
parser.pathname; // => "/path/"
parser.search;   // => "?search=test"
parser.hash;     // => "#hash"
parser.host;     // => "example.com:3000"

使用这些,您可以根据要求改进验证功能。唯一的缺点是它将接受相对 URL 并使用当前页面服务器的主机和端口。但是您可以利用它来发挥自己的优势,通过从部分重新组装 URL 并始终将其完整地传递给您的 AJAX 服务。

validateURL 不接受无效的 URL,例如http:\:8883 将返回 false,但 :1234 有效并被解释为 http://pagehost.example.com/:1234,即作为相对路径。

更新

这种方法不再适用于 Chrome 和其他 WebKit 浏览器。即使 URL 无效,主机名也会填充一些值,例如取自base。它仍然有助于解析部分 URL,但不允许验证一个。

可能更好的无解析器方法是使用var parsedURL = new URL(url) 并捕获异常。参见例如URL API。受所有主流浏览器和 NodeJS 支持,但仍标记为实验性。

【讨论】:

这将为&lt;script&gt;alert();&lt;/script&gt;返回TRUE @Subin 在现代浏览器中,此答案中的方法不再有效。感谢您关注它。事实上,无论你传递什么字符串,都会填充主机名。【参考方案4】:

您可以使用最近标准的URL API。浏览器支持充其量是粗略的,请参阅链接。 new URL(str) 保证为无效 URL 抛出 TypeError

如上所述,http://wwww 是一个有效的 URL。

【讨论】:

【参考方案5】:

我的解决方案:

function isValidUrl(t)

    return t.match(/^(http|https|ftp):\/\/(([A-Z0-9][A-Z0-9_-]*)(\.[A-Z0-9][A-Z0-9_-]*)+)(:(\d+))?\/?/i)

【讨论】:

【参考方案6】:
function validateURL(textval) 
    var urlregex = /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]2|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]2|[1-9]?[0-9]))3|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]2))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/;
    return urlregex.test(textval);

这可以为以下 URL 返回 true:

http://***.com/questions/1303872/url-validation-using-javascript

或:

http://regexlib.com/DisplayPatterns.aspx?cattabindex=1&categoryId=2

【讨论】:

为什么是RegExp 构造函数?文字在这里很好。为什么要将对象分配给变量? function validateURL(textval) return /^(http...$/.test(textval) 略短且清晰。 [...&...] 不会像您期望的那样。字符类不允许使用字符串。 此网址合法,但未通过验证:uk.reuters.com/article/2013/02/25/…(去掉末尾的 20130225 有效) asdf.asdf 用这个返回 true。为什么? 这一切都取决于您对“有效网址”的理解。您给出的所有示例在粘贴到浏览器地址栏时都可以工作(被认为是有效的),并且在用作 &lt;a href=""&gt; 的值时很可能会失败(被认为是无效的)。【参考方案7】:

在 npm 包中导入,如

https://www.npmjs.com/package/valid-url

并使用它来验证您的网址。

【讨论】:

github问题让人觉得库质量不够【参考方案8】:

我找到了一个很好的资源来比较不同的解决方案: https://mathiasbynens.be/demo/url-regex

根据该页面,只有 diegoperini 的解决方案通过了所有测试。这是正则表达式:

_^(?:(?:https?|ftp)://)(?:\S+(?::\S*)?@)?(?:(?!10(?:\.\d1,3)3)(?!127(?:\.\d1,3)3)(?!169\.254(?:\.\d1,3)2)(?!192\.168(?:\.\d1,3)2)(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d1,3)2)(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d1,2|2[0-4]\d|25[0-5]))2(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\x00a1-\xffff0-9]+-?)*[a-z\x00a1-\xffff0-9]+)(?:\.(?:[a-z\x00a1-\xffff0-9]+-?)*[a-z\x00a1-\xffff0-9]+)*(?:\.(?:[a-z\x00a1-\xffff]2,)))(?::\d2,5)?(?:/[^\s]*)?$_iuS

【讨论】:

【参考方案9】:

我知道这是一个很老的问题,但由于它没有任何可接受的答案,我建议您使用 URI.js 框架:https://github.com/medialize/URI.js

您可以使用 try/catch 块来检查格式错误的 URI:

function isValidURL(url)

    try 
        (new URI(url));
        return true;
    
    catch (e) 
        // Malformed URI
        return false;
    

当然,它会将“%@”之类的内容视为格式正确的相对 URI...所以我建议您阅读 URI.js API 以执行更多检查,例如,如果您想确保用户输入了格式正确的绝对 URL,您可以这样做:

function isValidURL(url)

    try 
        var uri = new URI(url);
        // URI has a scheme and a host
        return (!!uri.scheme() && !!uri.host());
    
    catch (e) 
        // Malformed URI
        return false;
    

【讨论】:

在 htt://localhost:86/asdfghjkl 上失败 你的 URL 是有效的,所以测试返回 true。我猜你想要做的是检查协议是http(s),然后在测试中添加一个!!uri.scheme().match(/^http(s?)$/)【参考方案10】:

这是一个可能符合要求的正则表达式(它很长):

/^(?:\u0066\u0069\u006C\u0065\u003A\u002F2(?:\u002F2(?:(?:[\u0041-\u005A\u0061-\u007A\u0030-\u0039\u002D\u002E\u005F\u007E\u0021\u0024\u0026\u0027\u0028\u0029\u002A\u002B\u002C\u003B\u003D]|\u0025[\u0030-\u0039\u0041-\u0046\u0061-\u0066][\u0030-\u0039\u0041-\u0046\u0061-\u0066])*\u0040)?(?:\u005B(?:(?:[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4\u003A)6(?:[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4\u003A[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4|(?:(?:[\u0030-\u0039]|[\u0031-\u0039][\u0030-\u0039]|\u0031[\u0030-\u0039]2|\u0032[\u0030-\u0034][\u0030-\u0039]|\u0032\u0035[\u0030-\u0035])\u002E)3(?:[\u0030-\u0039]|[\u0031-\u0039][\u0030-\u0039]|\u0031[\u0030-\u0039]2|\u0032[\u0030-\u0034][\u0030-\u0039]|\u0032\u0035[\u0030-\u0035]))|\u003A2(?:[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4\u003A)5(?:[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4\u003A[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4|(?:(?:[\u0030-\u0039]|[\u0031-\u0039][\u0030-\u0039]|\u0031[\u0030-\u0039]2|\u0032[\u0030-\u0034][\u0030-\u0039]|\u0032\u0035[\u0030-\u0035])\u002E)3(?:[\u0030-\u0039]|[\u0031-\u0039][\u0030-\u0039]|\u0031[\u0030-\u0039]2|\u0032[\u0030-\u0034][\u0030-\u0039]|\u0032\u0035[\u0030-\u0035]))|(?:[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4)?\u003A2(?:[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4\u003A)4(?:[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4\u003A[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4|(?:(?:[\u0030-\u0039]|[\u0031-\u0039][\u0030-\u0039]|\u0031[\u0030-\u0039]2|\u0032[\u0030-\u0034][\u0030-\u0039]|\u0032\u0035[\u0030-\u0035])\u002E)3(?:[\u0030-\u0039]|[\u0031-\u0039][\u0030-\u0039]|\u0031[\u0030-\u0039]2|\u0032[\u0030-\u0034][\u0030-\u0039]|\u0032\u0035[\u0030-\u0035]))|(?:(?:[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4\u003A)?[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4)?\u003A2(?:[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4\u003A)3(?:[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4\u003A[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4|(?:(?:[\u0030-\u0039]|[\u0031-\u0039][\u0030-\u0039]|\u0031[\u0030-\u0039]2|\u0032[\u0030-\u0034][\u0030-\u0039]|\u0032\u0035[\u0030-\u0035])\u002E)3(?:[\u0030-\u0039]|[\u0031-\u0039][\u0030-\u0039]|\u0031[\u0030-\u0039]2|\u0032[\u0030-\u0034][\u0030-\u0039]|\u0032\u0035[\u0030-\u0035]))|(?:(?:[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4\u003A)0,2[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4)?\u003A2(?:[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4\u003A)2(?:[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4\u003A[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4|(?:(?:[\u0030-\u0039]|[\u0031-\u0039][\u0030-\u0039]|\u0031[\u0030-\u0039]2|\u0032[\u0030-\u0034][\u0030-\u0039]|\u0032\u0035[\u0030-\u0035])\u002E)3(?:[\u0030-\u0039]|[\u0031-\u0039][\u0030-\u0039]|\u0031[\u0030-\u0039]2|\u0032[\u0030-\u0034][\u0030-\u0039]|\u0032\u0035[\u0030-\u0035]))|(?:(?:[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4\u003A)0,3[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4)?\u003A2[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4\u003A(?:[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4\u003A[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4|(?:(?:[\u0030-\u0039]|[\u0031-\u0039][\u0030-\u0039]|\u0031[\u0030-\u0039]2|\u0032[\u0030-\u0034][\u0030-\u0039]|\u0032\u0035[\u0030-\u0035])\u002E)3(?:[\u0030-\u0039]|[\u0031-\u0039][\u0030-\u0039]|\u0031[\u0030-\u0039]2|\u0032[\u0030-\u0034][\u0030-\u0039]|\u0032\u0035[\u0030-\u0035]))|(?:(?:[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4\u003A)0,4[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4)?\u003A2(?:[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4\u003A[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4|(?:(?:[\u0030-\u0039]|[\u0031-\u0039][\u0030-\u0039]|\u0031[\u0030-\u0039]2|\u0032[\u0030-\u0034][\u0030-\u0039]|\u0032\u0035[\u0030-\u0035])\u002E)3(?:[\u0030-\u0039]|[\u0031-\u0039][\u0030-\u0039]|\u0031[\u0030-\u0039]2|\u0032[\u0030-\u0034][\u0030-\u0039]|\u0032\u0035[\u0030-\u0035]))|(?:(?:[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4\u003A)0,5[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4)?\u003A2[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4|(?:(?:[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4\u003A)0,6[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4)?\u003A2)\u005D|(?:(?:[\u0030-\u0039]|[\u0031-\u0039][\u0030-\u0039]|\u0031[\u0030-\u0039]2|\u0032[\u0030-\u0034][\u0030-\u0039]|\u0032\u0035[\u0030-\u0035])\u002E)3(?:[\u0030-\u0039]|[\u0031-\u0039][\u0030-\u0039]|\u0031[\u0030-\u0039]2|\u0032[\u0030-\u0034][\u0030-\u0039]|\u0032\u0035[\u0030-\u0035])|(?:[\u0041-\u005A\u0061-\u007A\u0030-\u0039](?:(?:[\u0041-\u005A\u0061-\u007A\u0030-\u0039\u002D]+)?[\u0041-\u005A\u0061-\u007A\u0030-\u0039])?|(?:[\u0041-\u005A\u0061-\u007A\u0030-\u0039](?:(?:[\u0041-\u005A\u0061-\u007A\u0030-\u0039\u002D]+)?[\u0041-\u005A\u0061-\u007A\u0030-\u0039])?\u002E)+[\u0041-\u005A\u0061-\u007A\u0030-\u0039](?:(?:[\u0041-\u005A\u0061-\u007A\u0030-\u0039\u002D]+)?[\u0041-\u005A\u0061-\u007A\u0030-\u0039])?))(?:\u003A(?:\u0030-\u0035\u0030-\u00390,4|\u0036\u0030-\u0034\u0030-\u00393|\u0036\u0035\u0030-\u0034\u0030-\u00392|\u0036\u0035\u0035\u0030-\u0032\u0030-\u0039|\u0036\u0035\u0035\u0033\u0030-\u0035))?(?:\u002F(?:[\u0041-\u005A\u0061-\u007A\u0030-\u0039\u002D\u002E\u005F\u007E\u0021\u0024\u0026\u0027\u0028\u0029\u002A\u002B\u002C\u003B\u003D\u003A\u0040]|\u0025[\u0030-\u0039\u0041-\u0046\u0061-\u0066][\u0030-\u0039\u0041-\u0046\u0061-\u0066])*)*|\u002F(?:(?:[\u0041-\u005A\u0061-\u007A\u0030-\u0039\u002D\u002E\u005F\u007E\u0021\u0024\u0026\u0027\u0028\u0029\u002A\u002B\u002C\u003B\u003D\u003A\u0040]|\u0025[\u0030-\u0039\u0041-\u0046\u0061-\u0066][\u0030-\u0039\u0041-\u0046\u0061-\u0066])+(?:\u002F(?:[\u0041-\u005A\u0061-\u007A\u0030-\u0039\u002D\u002E\u005F\u007E\u0021\u0024\u0026\u0027\u0028\u0029\u002A\u002B\u002C\u003B\u003D\u003A\u0040]|\u0025[\u0030-\u0039\u0041-\u0046\u0061-\u0066][\u0030-\u0039\u0041-\u0046\u0061-\u0066])*)*)?|(?:[\u0041-\u005A\u0061-\u007A\u0030-\u0039\u002D\u002E\u005F\u007E\u0021\u0024\u0026\u0027\u0028\u0029\u002A\u002B\u002C\u003B\u003D\u003A\u0040]|\u0025[\u0030-\u0039\u0041-\u0046\u0061-\u0066][\u0030-\u0039\u0041-\u0046\u0061-\u0066])+(?:\u002F(?:[\u0041-\u005A\u0061-\u007A\u0030-\u0039\u002D\u002E\u005F\u007E\u0021\u0024\u0026\u0027\u0028\u0029\u002A\u002B\u002C\u003B\u003D\u003A\u0040]|\u0025[\u0030-\u0039\u0041-\u0046\u0061-\u0066][\u0030-\u0039\u0041-\u0046\u0061-\u0066])*)*)|[\u0041-\u005A\u0061-\u007A][\u0041-\u005A\u0061-\u007A\u0030-\u0039\u002B\u002D\u002E]*\u003A(?:\u002F2(?:(?:[\u0041-\u005A\u0061-\u007A\u0030-\u0039\u002D\u002E\u005F\u007E\u0021\u0024\u0026\u0027\u0028\u0029\u002A\u002B\u002C\u003B\u003D]|\u0025[\u0030-\u0039\u0041-\u0046\u0061-\u0066][\u0030-\u0039\u0041-\u0046\u0061-\u0066])*\u0040)?(?:\u005B(?:(?:[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4\u003A)6(?:[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4\u003A[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4|(?:(?:[\u0030-\u0039]|[\u0031-\u0039][\u0030-\u0039]|\u0031[\u0030-\u0039]2|\u0032[\u0030-\u0034][\u0030-\u0039]|\u0032\u0035[\u0030-\u0035])\u002E)3(?:[\u0030-\u0039]|[\u0031-\u0039][\u0030-\u0039]|\u0031[\u0030-\u0039]2|\u0032[\u0030-\u0034][\u0030-\u0039]|\u0032\u0035[\u0030-\u0035]))|\u003A2(?:[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4\u003A)5(?:[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4\u003A[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4|(?:(?:[\u0030-\u0039]|[\u0031-\u0039][\u0030-\u0039]|\u0031[\u0030-\u0039]2|\u0032[\u0030-\u0034][\u0030-\u0039]|\u0032\u0035[\u0030-\u0035])\u002E)3(?:[\u0030-\u0039]|[\u0031-\u0039][\u0030-\u0039]|\u0031[\u0030-\u0039]2|\u0032[\u0030-\u0034][\u0030-\u0039]|\u0032\u0035[\u0030-\u0035]))|(?:[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4)?\u003A2(?:[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4\u003A)4(?:[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4\u003A[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4|(?:(?:[\u0030-\u0039]|[\u0031-\u0039][\u0030-\u0039]|\u0031[\u0030-\u0039]2|\u0032[\u0030-\u0034][\u0030-\u0039]|\u0032\u0035[\u0030-\u0035])\u002E)3(?:[\u0030-\u0039]|[\u0031-\u0039][\u0030-\u0039]|\u0031[\u0030-\u0039]2|\u0032[\u0030-\u0034][\u0030-\u0039]|\u0032\u0035[\u0030-\u0035]))|(?:(?:[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4\u003A)?[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4)?\u003A2(?:[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4\u003A)3(?:[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4\u003A[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4|(?:(?:[\u0030-\u0039]|[\u0031-\u0039][\u0030-\u0039]|\u0031[\u0030-\u0039]2|\u0032[\u0030-\u0034][\u0030-\u0039]|\u0032\u0035[\u0030-\u0035])\u002E)3(?:[\u0030-\u0039]|[\u0031-\u0039][\u0030-\u0039]|\u0031[\u0030-\u0039]2|\u0032[\u0030-\u0034][\u0030-\u0039]|\u0032\u0035[\u0030-\u0035]))|(?:(?:[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4\u003A)0,2[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4)?\u003A2(?:[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4\u003A)2(?:[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4\u003A[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4|(?:(?:[\u0030-\u0039]|[\u0031-\u0039][\u0030-\u0039]|\u0031[\u0030-\u0039]2|\u0032[\u0030-\u0034][\u0030-\u0039]|\u0032\u0035[\u0030-\u0035])\u002E)3(?:[\u0030-\u0039]|[\u0031-\u0039][\u0030-\u0039]|\u0031[\u0030-\u0039]2|\u0032[\u0030-\u0034][\u0030-\u0039]|\u0032\u0035[\u0030-\u0035]))|(?:(?:[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4\u003A)0,3[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4)?\u003A2[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4\u003A(?:[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4\u003A[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4|(?:(?:[\u0030-\u0039]|[\u0031-\u0039][\u0030-\u0039]|\u0031[\u0030-\u0039]2|\u0032[\u0030-\u0034][\u0030-\u0039]|\u0032\u0035[\u0030-\u0035])\u002E)3(?:[\u0030-\u0039]|[\u0031-\u0039][\u0030-\u0039]|\u0031[\u0030-\u0039]2|\u0032[\u0030-\u0034][\u0030-\u0039]|\u0032\u0035[\u0030-\u0035]))|(?:(?:[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4\u003A)0,4[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4)?\u003A2(?:[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4\u003A[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4|(?:(?:[\u0030-\u0039]|[\u0031-\u0039][\u0030-\u0039]|\u0031[\u0030-\u0039]2|\u0032[\u0030-\u0034][\u0030-\u0039]|\u0032\u0035[\u0030-\u0035])\u002E)3(?:[\u0030-\u0039]|[\u0031-\u0039][\u0030-\u0039]|\u0031[\u0030-\u0039]2|\u0032[\u0030-\u0034][\u0030-\u0039]|\u0032\u0035[\u0030-\u0035]))|(?:(?:[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4\u003A)0,5[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4)?\u003A2[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4|(?:(?:[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4\u003A)0,6[\u0030-\u0039\u0041-\u0046\u0061-\u0066]1,4)?\u003A2)\u005D|(?:(?:[\u0030-\u0039]|[\u0031-\u0039][\u0030-\u0039]|\u0031[\u0030-\u0039]2|\u0032[\u0030-\u0034][\u0030-\u0039]|\u0032\u0035[\u0030-\u0035])\u002E)3(?:[\u0030-\u0039]|[\u0031-\u0039][\u0030-\u0039]|\u0031[\u0030-\u0039]2|\u0032[\u0030-\u0034][\u0030-\u0039]|\u0032\u0035[\u0030-\u0035])|(?:[\u0041-\u005A\u0061-\u007A\u0030-\u0039](?:(?:[\u0041-\u005A\u0061-\u007A\u0030-\u0039\u002D]+)?[\u0041-\u005A\u0061-\u007A\u0030-\u0039])?|(?:[\u0041-\u005A\u0061-\u007A\u0030-\u0039](?:(?:[\u0041-\u005A\u0061-\u007A\u0030-\u0039\u002D]+)?[\u0041-\u005A\u0061-\u007A\u0030-\u0039])?\u002E)+[\u0041-\u005A\u0061-\u007A\u0030-\u0039](?:(?:[\u0041-\u005A\u0061-\u007A\u0030-\u0039\u002D]+)?[\u0041-\u005A\u0061-\u007A\u0030-\u0039])?))(?:\u003A(?:\u0030-\u0035\u0030-\u00390,4|\u0036\u0030-\u0034\u0030-\u00393|\u0036\u0035\u0030-\u0034\u0030-\u00392|\u0036\u0035\u0035\u0030-\u0032\u0030-\u0039|\u0036\u0035\u0035\u0033\u0030-\u0035))?(?:\u002F(?:[\u0041-\u005A\u0061-\u007A\u0030-\u0039\u002D\u002E\u005F\u007E\u0021\u0024\u0026\u0027\u0028\u0029\u002A\u002B\u002C\u003B\u003D\u003A\u0040]|\u0025[\u0030-\u0039\u0041-\u0046\u0061-\u0066][\u0030-\u0039\u0041-\u0046\u0061-\u0066])*)*|\u002F(?:(?:[\u0041-\u005A\u0061-\u007A\u0030-\u0039\u002D\u002E\u005F\u007E\u0021\u0024\u0026\u0027\u0028\u0029\u002A\u002B\u002C\u003B\u003D\u003A\u0040]|\u0025[\u0030-\u0039\u0041-\u0046\u0061-\u0066][\u0030-\u0039\u0041-\u0046\u0061-\u0066])+(?:\u002F(?:[\u0041-\u005A\u0061-\u007A\u0030-\u0039\u002D\u002E\u005F\u007E\u0021\u0024\u0026\u0027\u0028\u0029\u002A\u002B\u002C\u003B\u003D\u003A\u0040]|\u0025[\u0030-\u0039\u0041-\u0046\u0061-\u0066][\u0030-\u0039\u0041-\u0046\u0061-\u0066])*)*)?|(?:[\u0041-\u005A\u0061-\u007A\u0030-\u0039\u002D\u002E\u005F\u007E\u0021\u0024\u0026\u0027\u0028\u0029\u002A\u002B\u002C\u003B\u003D\u003A\u0040]|\u0025[\u0030-\u0039\u0041-\u0046\u0061-\u0066][\u0030-\u0039\u0041-\u0046\u0061-\u0066])+(?:\u002F(?:[\u0041-\u005A\u0061-\u007A\u0030-\u0039\u002D\u002E\u005F\u007E\u0021\u0024\u0026\u0027\u0028\u0029\u002A\u002B\u002C\u003B\u003D\u003A\u0040]|\u0025[\u0030-\u0039\u0041-\u0046\u0061-\u0066][\u0030-\u0039\u0041-\u0046\u0061-\u0066])*)*)(?:\u003F(?:[\u0041-\u005A\u0061-\u007A\u0030-\u0039\u002D\u002E\u005F\u007E\u0021\u0024\u0026\u0027\u0028\u0029\u002A\u002B\u002C\u003B\u003D\u003A\u0040\u002F\u003F]|\u0025[\u0030-\u0039\u0041-\u0046\u0061-\u0066][\u0030-\u0039\u0041-\u0046\u0061-\u0066])*)?(?:\u0023(?:[\u0041-\u005A\u0061-\u007A\u0030-\u0039\u002D\u002E\u005F\u007E\u0021\u0024\u0026\u0027\u0028\u0029\u002A\u002B\u002C\u003B\u003D\u003A\u0040\u002F\u003F]|\u0025[\u0030-\u0039\u0041-\u0046\u0061-\u0066][\u0030-\u0039\u0041-\u0046\u0061-\u0066])*)?)$/

它的使用有一些注意事项,即它不验证在用户名之后包含附加信息的 URI(例如“用户名:密码”)。此外,IP 文字语法中只能包含 IPv6 地址,并且“IPvFuture”语法当前被忽略,并且不会针对此正则表达式进行验证。端口号也被限制在 0 到 65,535 之间。此外,只有文件方案可以使用三斜杠(例如“file:///etc/sysconfig”),并且可以忽略 URI 的查询和片段部分。最后,它面向常规 URI 而不是 IRI,因此广泛关注 ASCII 字符集。

这个正则表达式可以扩展,但它已经很复杂并且足够长了。我也不能保证它将是“100% 准确”或“无错误”,但它应该正确验证所有方案的 URI。

您需要对任何特定于方案的要求进行额外验证或进行 URI 规范化,因为此正则表达式将验证范围非常广泛的 URI。

【讨论】:

【参考方案11】:

尝试如下编辑您的isValidURL 函数:

function isValidURL(url) 
    var encodedURL = encodeURIComponent(url);
    var isValid = false;

    $.ajax(
      url: "http://query.yahooapis.com/v1/public/yql?q=select%20*%20from%20html%20where%20url%3D%22" + encodedURL + "%22&format=json",
      type: "get",
      async: false,
      dataType: "json",
      success: function(data) 
        isValid = data.query.results != null;
      ,
      error: function()
        isValid = false;
      
    );

    return isValid;

这应该可以解决问题。

【讨论】:

因为 ajax 是异步的,isValid 总是返回 false,对吧? 没有。 Ajax 是异步的,但请看一下调用。它指定“异步:假”。 最好避免同步调用,因为它们会影响性能。还有一个问题是,如果您的网络出现故障,这里的函数将返回不正确的结果。此外,它还会将你所有的网址泄露给雅虎。【参考方案12】:
var RegExp = (/^HTTP|HTTP|http(s)?:\/\/(www\.)?[A-Za-z0-9]+([\-\.]1[A-Za-z0-9]+)*\.[A-Za-z]2,40(:[0-9]1,40)?(\/.*)?$/);

【讨论】:

【参考方案13】:

我还写了一个基于 rfc1738 和 rfc3986 的 URL 验证函数来检查 http 和 https url。我尝试保持这个模块化,以便更好地维护和适应自己的需求。

一行中的正则表达式显示在本文末尾。

RegExp 接受带有一些国际域或 IPv4 号码的 HTTP 和 HTTPS URL。尚不支持 IPv6。

window.isValidURL = (function() // wrapped in self calling function to prevent global pollution

     //URL pattern based on rfc1738 and rfc3986
    var rg_pctEncoded = "%[0-9a-fA-F]2";
    var rg_protocol = "(http|https):\\/\\/";

    var rg_userinfo = "([a-zA-Z0-9$\\-_.+!*'(),;:&=]|" + rg_pctEncoded + ")+" + "@";

    var rg_decOctet = "(25[0-5]|2[0-4][0-9]|[0-1][0-9][0-9]|[1-9][0-9]|[0-9])"; // 0-255
    var rg_ipv4address = "(" + rg_decOctet + "(\\." + rg_decOctet + ")3" + ")";
    var rg_hostname = "([a-zA-Z0-9\\-\\u00C0-\\u017F]+\\.)+([a-zA-Z]2,)";
    var rg_port = "[0-9]+";

    var rg_hostport = "(" + rg_ipv4address + "|localhost|" + rg_hostname + ")(:" + rg_port + ")?";

    // chars sets
    // safe           = "$" | "-" | "_" | "." | "+"
    // extra          = "!" | "*" | "'" | "(" | ")" | ","
    // hsegment       = *[ alpha | digit | safe | extra | ";" | ":" | "@" | "&" | "=" | escape ]
    var rg_pchar = "a-zA-Z0-9$\\-_.+!*'(),;:@&=";
    var rg_segment = "([" + rg_pchar + "]|" + rg_pctEncoded + ")*";

    var rg_path = rg_segment + "(\\/" + rg_segment + ")*";
    var rg_query = "\\?" + "([" + rg_pchar + "/?]|" + rg_pctEncoded + ")*";
    var rg_fragment = "\\#" + "([" + rg_pchar + "/?]|" + rg_pctEncoded + ")*";

    var rgHttpUrl = new RegExp( 
        "^"
        + rg_protocol
        + "(" + rg_userinfo + ")?"
        + rg_hostport
        + "(\\/"
        + "(" + rg_path + ")?"
        + "(" + rg_query + ")?"
        + "(" + rg_fragment + ")?"
        + ")?"
        + "$"
    );

    // export public function
    return function (url) 
        if (rgHttpUrl.test(url)) 
            return true;
         else 
            return false;
        
    ;
)();

一行中的正则表达式:

var rg = /^(http|https):\/\/(([a-zA-Z0-9$\-_.+!*'(),;:&=]|%[0-9a-fA-F]2)+@)?(((25[0-5]|2[0-4][0-9]|[0-1][0-9][0-9]|[1-9][0-9]|[0-9])(\.(25[0-5]|2[0-4][0-9]|[0-1][0-9][0-9]|[1-9][0-9]|[0-9]))3)|localhost|([a-zA-Z0-9\-\u00C0-\u017F]+\.)+([a-zA-Z]2,))(:[0-9]+)?(\/(([a-zA-Z0-9$\-_.+!*'(),;:@&=]|%[0-9a-fA-F]2)*(\/([a-zA-Z0-9$\-_.+!*'(),;:@&=]|%[0-9a-fA-F]2)*)*)?(\?([a-zA-Z0-9$\-_.+!*'(),;:@&=\/?]|%[0-9a-fA-F]2)*)?(\#([a-zA-Z0-9$\-_.+!*'(),;:@&=\/?]|%[0-9a-fA-F]2)*)?)?$/;

【讨论】:

这太棒了!将它分解成不同的部分非常有帮助 - 我不想只是盲目地相信大量的正则表达式。【参考方案14】:

我从http://angularjs.org/找到的最佳正则表达式

var urlregex = /^(ftp|http|https):\/\/(\w+:0,1\w*@)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&amp;%@!\-\/]))?$/;

【讨论】:

如果我测试这个:---- /^(ftp|http|https):\/\/(\w+:0,1\w*@)?(\S+) (:[0-9]+)?(\/|\/([\w#!:.?+=&%@!\-\/]))?$/.test('abc.com.com.com') 它返回真值。我认为它应该只允许 2 .com 在 url 中。【参考方案15】:

演示:http://jsbin.com/uzimeb/1/edit

function checkURL(value) 
    var urlregex = new RegExp("^(http|https|ftp)\://([a-zA-Z0-9\.\-]+(\:[a-zA-Z0-9\.&amp;%\$\-]+)*@)*((25[0-5]|2[0-4][0-9]|[0-1]1[0-9]2|[1-9]1[0-9]1|[1-9])\.(25[0-5]|2[0-4][0-9]|[0-1]1[0-9]2|[1-9]1[0-9]1|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]1[0-9]2|[1-9]1[0-9]1|[1-9]|0)\.(25[0-5]|2[0-4][0-9]|[0-1]1[0-9]2|[1-9]1[0-9]1|[0-9])|([a-zA-Z0-9\-]+\.)*[a-zA-Z0-9\-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]2))(\:[0-9]+)*(/($|[a-zA-Z0-9\.\,\?\'\\\+&amp;%\$#\=~_\-]+))*$");
    if (urlregex.test(value)) 
        return (true);
    
    return (false);

【讨论】:

【参考方案16】:

这对我有用:

function validateURL(value) 
    return /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]2)|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]2)|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]2)|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]2)|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]2)|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(value);
    

这里只是调用函数来获取真或假的问题:

validateURL(urltovalidate);

【讨论】:

注意,ip 地址会失败。【参考方案17】:

使用正则表达式解析 URL 是不切实际的。 RFC1738 规则的完整实现将导致非常长的正则表达式(假设它甚至是可能的)。当然,您当前的表达式会失败许多有效的 URL,并传递无效的 URL。

改为:

一个。使用真正遵循真实规则的正确 URL 解析器。 (我不知道有一个用于 JavaScript 的;它可能会有点矫枉过正。不过你可以在服务器端做)。或者,

b.只需剪掉任何前导或尾随空格,然后检查它的前面是否有您首选的方案之一(通常是“http://”或“https://”),然后保留它。或者,

c。尝试使用 URL 并查看最后的内容,例如通过从服务器端发送 HTTP HEAD 请求。如果您收到 404 或连接错误,则可能是错误的。

即使 url 类似于“http://wwww”,它也会返回 true。

嗯,这确实是一个完全有效的 URL。

如果您想检查诸如“wwww”之类的主机名是否确实存在,您别无选择,只能在 DNS 中查找。同样,这将是服务器端代码。

【讨论】:

这是务实的吗?是的。它是否回答了问题或为实现实现提供了足够的信息?没有。 对于匹配 IRI (RFC 3987) 的正则表达式,请参阅“Regular expression for W3C compliant URLs?”。请注意,这将匹配任何 IRIs,而不仅仅是 URL (RFC 1738) 或 URI (RFC 3986)。【参考方案18】:

如果您正在寻找更可靠的正则表达式,请查看 RegexLib。这是您可能感兴趣的页面:

http://regexlib.com/Search.aspx?k=url

至于该人仍在打字时显示的错误消息,将事件从keydown更改为blur,然后它只会在该人移动到下一个元素时检查。

【讨论】:

以上是关于尝试使用 JavaScript 验证 URL的主要内容,如果未能解决你的问题,请参考以下文章

尝试通过Javascript验证表单,但代码不起作用

使用Javascript / jQuery进行Bootstrap 4表单验证

使用 Javascript /jQuery 的 Bootstrap 4 表单验证

使用 javascript 验证电话号码

使用 Javascript 验证电台选择 [重复]

带有标头的基本身份验证 - Javascript XMLHttpRequest