在JavaScript中是否有一种方法来检查字符串是否是URL?
regex被排除在外,因为URL很可能写成stackoverflow;也就是说,它可能没有。com, WWW或http。
在JavaScript中是否有一种方法来检查字符串是否是URL?
regex被排除在外,因为URL很可能写成stackoverflow;也就是说,它可能没有。com, WWW或http。
当前回答
这显然不是最有效的方法,但它是可读的,并且很容易形成您需要的任何形式。从这里添加regex/complexity更容易。这是一个非常实用的方法
const validFirstBits = ["ftp://", "http://", "https://", "www."];
const invalidPatterns = [" ", "//.", ".."];
export function isUrl(word) {
// less than www.1.dk
if (!word || word.length < 8) return false;
// Let's check and see, if our candidate starts with some of our valid first bits
const firstBitIsValid = validFirstBits.some(bit => word.indexOf(bit) === 0);
if (!firstBitIsValid) return false;
const hasInvalidPatterns = invalidPatterns.some(
pattern => word.indexOf(pattern) !== -1,
);
if (hasInvalidPatterns) return false;
const dotSplit = word.split(".");
if (dotSplit.length > 1) {
const lastBit = dotSplit.pop(); // string or undefined
if (!lastBit) return false;
const length = lastBit.length;
const lastBitIsValid =
length > 1 || (length === 1 && !isNaN(parseInt(lastBit)));
return !!lastBitIsValid;
}
return false;
}
测试:
import { isUrl } from "./foo";
describe("Foo", () => {
test("should validate correct urls correctly", function() {
const validUrls = [
"http://example.com",
"http://example.com/blah",
"http://127.0.0.1",
"http://127.0.0.1/wow",
"https://example.com",
"https://example.com/blah",
"https://127.0.0.1:1234",
"ftp://example.com",
"ftp://example.com/blah",
"ftp://127.0.0.1",
"www.example.com",
"www.example.com/blah",
];
validUrls.forEach(url => {
expect(isUrl(url) && url).toEqual(url);
});
});
test("should validate invalid urls correctly", function() {
const inValidUrls = [
"http:// foo.com",
"http:/foo.com",
"http://.foo.com",
"http://foo..com",
"http://.com",
"http://foo",
"http://foo.c",
];
inValidUrls.forEach(url => {
expect(!isUrl(url) && url).toEqual(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域。
一个有答案的相关问题
或者来自Devshed的Regexp:
function validURL(str) {
var pattern = new RegExp('^(https?:\\/\\/)?'+ // protocol
'((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|'+ // domain name
'((\\d{1,3}\\.){3}\\d{1,3}))'+ // OR ip (v4) address
'(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*'+ // port and path
'(\\?[;&a-z\\d%_.~+=-]*)?'+ // query string
'(\\#[-a-z\\d_]*)?$','i'); // fragment locator
return !!pattern.test(str);
}
有几个使用URL构造函数的测试,没有描述输入是字符串还是URL对象。
// Testing whether something is a URL
function isURL(url) {
return toString.call(url) === "[object URL]";
}
// Testing whether the input is both a string and valid url:
function isUrl(url) {
try {
return toString.call(url) === "[object String]" && !!(new URL(url));
} catch (_) {
return false;
}
}
该功能不允许localhost,只允许web页面的url(即只允许http或https协议)。
它也只允许这里定义的安全字符:https://www.urlencoder.io/learn/
function isValidWebUrl(url) {
let regEx = /^https?:\/\/(?:www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)$/gm;
return regEx.test(url);
}
这显然不是最有效的方法,但它是可读的,并且很容易形成您需要的任何形式。从这里添加regex/complexity更容易。这是一个非常实用的方法
const validFirstBits = ["ftp://", "http://", "https://", "www."];
const invalidPatterns = [" ", "//.", ".."];
export function isUrl(word) {
// less than www.1.dk
if (!word || word.length < 8) return false;
// Let's check and see, if our candidate starts with some of our valid first bits
const firstBitIsValid = validFirstBits.some(bit => word.indexOf(bit) === 0);
if (!firstBitIsValid) return false;
const hasInvalidPatterns = invalidPatterns.some(
pattern => word.indexOf(pattern) !== -1,
);
if (hasInvalidPatterns) return false;
const dotSplit = word.split(".");
if (dotSplit.length > 1) {
const lastBit = dotSplit.pop(); // string or undefined
if (!lastBit) return false;
const length = lastBit.length;
const lastBitIsValid =
length > 1 || (length === 1 && !isNaN(parseInt(lastBit)));
return !!lastBitIsValid;
}
return false;
}
测试:
import { isUrl } from "./foo";
describe("Foo", () => {
test("should validate correct urls correctly", function() {
const validUrls = [
"http://example.com",
"http://example.com/blah",
"http://127.0.0.1",
"http://127.0.0.1/wow",
"https://example.com",
"https://example.com/blah",
"https://127.0.0.1:1234",
"ftp://example.com",
"ftp://example.com/blah",
"ftp://127.0.0.1",
"www.example.com",
"www.example.com/blah",
];
validUrls.forEach(url => {
expect(isUrl(url) && url).toEqual(url);
});
});
test("should validate invalid urls correctly", function() {
const inValidUrls = [
"http:// foo.com",
"http:/foo.com",
"http://.foo.com",
"http://foo..com",
"http://.com",
"http://foo",
"http://foo.c",
];
inValidUrls.forEach(url => {
expect(!isUrl(url) && url).toEqual(url);
});
});
});