在JavaScript中是否有一种方法来检查字符串是否是URL?

regex被排除在外,因为URL很可能写成stackoverflow;也就是说,它可能没有。com, WWW或http。


当前回答

您可以使用ajax请求来检查字符串是否有效的url和可访问的

(function() { $("input").change(function() { const check = $.ajax({ url : this.value, dataType: "jsonp" }); check.then(function() { console.log("Site is valid and registered"); }); //expected output check.catch(function(reason) { if(reason.status === 200) { return console.log("Site is valid and registered"); } console.log("Not a valid site"); }) }); })() <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> <input type="text" placeholder="Please input url to check ? ">

其他回答

Mathias Bynens编译了一个带有测试URL的知名URL正则表达式列表。没有什么理由去写一个新的正则表达式;只要选择一个现有的最适合你的。

但是这些正则表达式的比较表也表明,使用单个正则表达式进行URL验证几乎是不可能的。Bynens列出的所有正则表达式都会产生假阳性和假阴性。

我建议您使用现有的URL解析器(例如JavaScript中的新URL('http://www.example.com/')),然后应用您想要对URL响应的解析和规范化形式执行的检查。它的组件。使用JavaScript URL接口还有一个额外的好处,它只接受浏览器真正接受的URL。

您还应该记住,技术上不正确的url仍然可以工作。例如http://w_w_w.example.com/, http://www..example.com/, http://123.example.com/都有一个无效的主机名部分,但我知道的每个浏览器都会试图打开它们而没有抱怨,当你在/etc/hosts/中为这些无效的名称指定IP地址时,这样的url甚至可以工作,但只在你的计算机上。

因此,问题不在于URL是否有效,而在于在特定的上下文中应该允许哪些URL工作。

如果你想进行URL验证,有很多细节和边缘情况很容易被忽视:

URLs may contain credentials as in http://user:password@www.example.com/. Port numbers must be in the range of 0-65535, but you may still want to exclude the wildcard port 0. Port numbers may have leading zeros as in http://www.example.com:000080/. IPv4 addresses are by no means restricted to 4 decimal integers in the range of 0-255. You can use one to four integers, and they can be decimal, octal or hexadecimal. The URLs https://010.010.000010.010/, https://0x8.0x8.0x0008.0x8/, https://8.8.2056/, https://8.526344/, https://134744072/ are all valid and just creative ways of writing https://8.8.8.8/. Allowing loopback addresses (http://127.0.0.1/), private IP addresses (http://192.168.1.1), link-local addresses (http://169.254.100.200) and so on may have an impact on security or privacy. If, for instance, you allow them as the address of user avatars in a forum, you cause the users' browsers to send unsolicited network requests in their local network and in the internet of things such requests may cause funny and not so funny things to happen in your home. For the same reasons, you may want to discard links to not fully qualified hostnames, in other words hostnames without a dot. But hostnames may always have a trailing dot (like in http://www.stackoverflow.com.). The hostname portion of a link may contain angle brackets for IPv6 addresses as in http://[::1]. IPv6 addresses also have ranges for private networks or link-local addresses etc. If you block certain IPv4 addresses, keep in mind that for example https://127.0.0.1 and https://[::ffff:127.0.0.1] point to the same resource (if the loopback device of your machine is IPv6 ready). The hostname portion of URLs may now contain Unicode, so that the character range [-0-9a-zA-z] is definitely no longer sufficient. Many registries for top-level domains define specific restrictions, for example on the allowed set of Unicode characters. Or they subdivide their namespace (like co.uk and many others). Top-level domains must not contain decimal digits, and the hyphen is not allowed unless for the IDN A-label prefix "xn--". Unicode top-level domains (and their punycode encoding with "xn--") must still contain only letters but who wants to check that in a regex?

应用哪些限制和规则取决于项目需求和喜好。

我最近为一个web应用程序编写了一个URL验证器,它适用于论坛、社交网络等用户提供的URL。你可以把它作为你自己的基础:

(Angular)前端的JavaScript/Typescript版本 Perl版本的后端

我还写了一篇博客文章《URL验证的血淋淋的细节》,提供了更深入的信息。

2020年更新。 为了扩展@iamnewton和@ fernando Chavez Herrera的精彩回答,我已经开始看到@被用于url的路径。

所以更新后的正则表达式是:

RegExp('(https?:\\/\\/)?((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|((\\d{1,3}\\.){3}\\d{1,3}))(\\:\\d+)?(\\/[-a-z\\d%_.~+@]*)*(\\?[;&a-z\\d%_.~+=-]*)?(\\#[-a-z\\d_]*)?$', 'i');

如果你想在查询字符串和哈希中允许它,使用:

RegExp('(https?:\\/\\/)?((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|((\\d{1,3}\\.){3}\\d{1,3}))(\\:\\d+)?(\\/[-a-z\\d%_.~+@]*)*(\\?[;&a-z\\d%_.~+=-@]*)?(\\#[-a-z\\d_@]*)?$', 'i');

话虽如此,我不确定是否有白皮书规则禁止在查询字符串或哈希中使用@。

依赖库: https://www.npmjs.com/package/valid-url

import { isWebUri } from 'valid-url';
// ...
if (!isWebUri(url)) {
    return "Not a valid url.";
}

这似乎是CS中最难的问题之一;)

这是另一个不完整的解决方案,它对我来说足够好,比我在这里看到的其他解决方案更好。为了支持IE11,我使用了一个输入[type=url],否则使用window会简单得多。URL来执行验证:

const ipv4Regex = /^(\d{1,3}\.){3}\d{1,3}$/; function isValidIpv4(ip) { if (!ipv4Regex.test(ip)) return false; return !ip.split('.').find(n => n > 255); } const domainRegex = /(?:[a-z0-9-]{1,63}\.){1,125}[a-z]{2,63}$/i; function isValidDomain(domain) { return isValidIpv4(domain) || domainRegex.test(domain); } let input; function validateUrl(url) { if (! /^https?:\/\//.test(url)) url = `http://${url}`; // assuming Babel is used // to support IE11 we'll resort to input[type=url] instead of window.URL: // try { return isValidDomain(new URL(url).host) && url; } catch(e) { return false; } if (!input) { input = document.createElement('input'); input.type = 'url'; } input.value = url; if (! input.validity.valid) return false; const domain = url.split(/^https?:\/\//)[1].split('/')[0].split('@').pop(); return isValidDomain(domain) && url; } console.log(validateUrl('google'), // false validateUrl('user:pw@mydomain.com'), validateUrl('https://google.com'), validateUrl('100.100.100.100/abc'), validateUrl('100.100.100.256/abc')); // false

为了接受不完整的输入,例如“www.mydomain.com”,它还将使其有效,假设在这些情况下协议是“http”,如果地址有效,则返回有效的URL。无效时返回false。

它还支持IPv4域,但不支持IPv6域。

这是@palvo的答案的扩展。

function isValidHttpUrl(string) {
  let url;
  try {
    url = new URL(string);
  } catch (_) {
    return false;  
  }
  return (url.protocol === "http:" || url.protocol === "https:") && (url.href == string || url.origin == string);
}

试试以下方法:-

isValidHttpUrl(“https:母羊/ dsdsd”); isValidHttpUrl(“https://ewe/dsdsd”);

Chrome测试