在JavaScript中是否有一种方法来检查字符串是否是URL?
regex被排除在外,因为URL很可能写成stackoverflow;也就是说,它可能没有。com, WWW或http。
在JavaScript中是否有一种方法来检查字符串是否是URL?
regex被排除在外,因为URL很可能写成stackoverflow;也就是说,它可能没有。com, WWW或http。
当前回答
该问题询问一个url(如stackoverflow)的验证方法,而没有协议或主机名中的任何点。因此,这不是验证url sintax的问题,而是通过实际调用它来检查它是否是一个有效的url。
我尝试了几种方法来知道url是否真实存在,并且可以从浏览器中调用,但没有找到任何方法来测试javascript调用的响应头:
添加一个锚元素可以触发click()方法。 使用'GET'对具有挑战性的url进行ajax调用是可以的,但由于CORS政策,它有各种限制,并且不是使用ajax的情况,因为url可能在我的服务器域之外。 使用fetch API有一个类似ajax的解决方案。 另一个问题是,我有我的服务器在https协议下,并在调用非安全url时抛出异常。
所以,我能想到的最好的解决方案是得到一些工具来执行CURL使用javascript尝试像CURL -I <url>。不幸的是,我没有找到任何,在外观上,这是不可能的。我将感谢任何关于这一点的评论。
但是,最后,我有一个运行PHP的服务器,因为我几乎所有的请求都使用Ajax,所以我在服务器端编写了一个函数来执行curl请求并返回到浏览器。
关于“stackoverflow”问题上的单个单词url,它将引导我到https://daniserver.com.ar/stackoverflow,其中daniserver.com.ar是我自己的域名。
其他回答
我认为使用本地URL API比@pavlo建议的复杂正则表达式模式更好。虽然它有一些缺点,但我们可以通过一些额外的代码来修复。对于以下有效url,此方法失败。
//cdn.google.com/script.js
我们可以预先添加缺失的协议来避免这种情况。它也无法检测以下无效的url。
http://w
http://..
那么为什么要检查整个url呢?我们可以检查定义域。我借用正则表达式从这里验证域。
function isValidUrl(string) {
if (string && string.length > 1 && string.slice(0, 2) == '//') {
string = 'http:' + string; //dummy protocol so that URL works
}
try {
var url = new URL(string);
return url.hostname && url.hostname.match(/^([a-z0-9])(([a-z0-9-]{1,61})?[a-z0-9]{1})?(\.[a-z0-9](([a-z0-9-]{1,61})?[a-z0-9]{1})?)?(\.[a-zA-Z]{2,4})+$/) ? true : false;
} catch (_) {
return false;
}
}
主机名属性是javascript:void(0)的空字符串,所以它也适用于此,你也可以添加IP地址验证器。我最喜欢坚持使用本地API,并希望它在不久的将来开始支持一切。
我建议使用锚元素,而不是使用正则表达式。
当你设置一个锚的href属性时,其他各种属性也会被设置。
var parser = document.createElement('a');
parser.href = "http://example.com:3000/pathname/?search=test#hash";
parser.protocol; // => "http:"
parser.hostname; // => "example.com"
parser.port; // => "3000"
parser.pathname; // => "/pathname/"
parser.search; // => "?search=test"
parser.hash; // => "#hash"
parser.host; // => "example.com:3000"
源
但是,如果href绑定的值不是一个有效的url,那么这些辅助属性的值将是空字符串。
编辑:正如评论中指出的:如果使用了无效的url,则可以替换当前url的属性。
所以,只要你没有传递当前页面的URL,你可以这样做:
function isValidURL(str) {
var a = document.createElement('a');
a.href = str;
return (a.host && a.host != window.location.host);
}
一个有答案的相关问题
或者来自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);
}
这里只是一个非常简单的检查,以确保有一个有效的协议,并且域扩展名必须是两个或更多字符。
is_valid_url = ( $url ) => {
let $url_object = null;
try {
$url_object = new URL( $url );
} catch ( $error ) {
return false;
}
const $protocol = $url_object.protocol;
const $protocol_position = $url.lastIndexOf( $protocol );
const $domain_extension_position = $url.lastIndexOf( '.' );
return (
$protocol_position === 0 &&
[ 'http:', 'https:' ].indexOf( $protocol ) !== - 1 &&
$domain_extension_position > 2 && $url.length - $domain_extension_position > 2
);
};
和我一起工作
function isURL(str) {
var regex = /(http|https):\/\/(\w+:{0,1}\w*)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%!\-\/]))?/;
var pattern = new RegExp(regex);
return pattern.test(str);
}