javascript-如何测试URL字符串是绝对字符串还是相对字符串?

如果URL是Javascript或jQuery中的相对或绝对路径,该如何测试? 我想根据传入的URL是本地路径还是外部路径来进行相应的处理。

if (urlString starts with http:// or https://)
 //do this
TruMan1 asked 2019-10-09T12:36:02Z
12个解决方案
129 votes

快速

如果您只需要测试http://https://,那么最有效的方法是:

if (urlString.indexOf('http://') === 0 || urlString.indexOf('https://') === 0)

普遍

但是,我建议一种更通用,不区分大小写,与协议无关的方法:

var r = new RegExp('^(?:[a-z]+:)?//', 'i');
r.test('http://example.com'); // true - regular http absolute URL
r.test('HTTP://EXAMPLE.COM'); // true - HTTP upper-case absolute URL
r.test('https://www.exmaple.com'); // true - secure http absolute URL
r.test('ftp://example.com/file.txt'); // true - file transfer absolute URL
r.test('//cdn.example.com/lib.js'); // true - protocol-relative absolute URL
r.test('/myfolder/test.txt'); // false - relative URL
r.test('test'); // false - also relative URL

解释RegExp

^(?:[a-z]+:)?//

^-字符串的开头
(?:-未捕获的组的开始
[a-z]+-从“ a”到“ z”的任意字符1次或更多次
:-字符串(冒号)
)?-未捕获组的末尾。 群组出现0或1次
//-字符串(两个正斜杠字符)
'i'-不区分大小写的标志

Geo answered 2019-10-09T12:38:11Z
29 votes
var pat = /^https?:\/\//i;
if (pat.test(urlString))
{
    //do stuff
}

对于协议相对URL,请使用此正则表达式:

/^https?:\/\/|^\/\//i

strah answered 2019-10-09T12:36:23Z
17 votes

使用正则表达式:

if (/^(?:[a-z]+:)?\/\//i.test(url))
SLaks answered 2019-10-09T12:38:39Z
13 votes

一个非常快速,非常灵活的检查是:

if (url.indexOf('://') > 0 || url.indexOf('//') === 0 ) {
    // URL is absolute; either "http://example.com" or "//example.com"
} else {
    // URL is relative
}

如果出现以下情况,它将识别出绝对URL:

  • URL的第一个字符后的任何地方都包含“://”,或者
  • 网址以“ //”开头(与协议有关)

  • 没有正则表达式。
  • 没有jQuery或其他依赖项。
  • 没有使条件区分大小写的硬编码协议名称。
  • 没有字符串操作(例如toLowerCase或类似内容)。
  • 只能用于“相对”或“绝对”检查,而不能进行其他任何健全性检查,可用于Web URL或任何内部协议。

更新

这是一个针对给定URL返回true / false的快速函数:

function isUrlAbsolute(url) { 
    return (url.indexOf('://') > 0 || url.indexOf('//') === 0);
}

同样在ES6中:

const isUrlAbsolute = (url) => (url.indexOf('://') > 0 || url.indexOf('//') === 0)

更新2

要另外寻址格式/redirect?target=http://example.org的URL,我建议使用以下代码:

function isUrlAbsolute(url) {
    if (url.indexOf('//') === 0) {return true;} // URL is protocol-relative (= absolute)
    if (url.indexOf('://') === -1) {return false;} // URL has no protocol (= relative)
    if (url.indexOf('.') === -1) {return false;} // URL does not contain a dot, i.e. no TLD (= relative, possibly REST)
    if (url.indexOf('/') === -1) {return false;} // URL does not contain a single slash (= relative)
    if (url.indexOf(':') > url.indexOf('/')) {return false;} // The first colon comes after the first slash (= relative)
    if (url.indexOf('://') < url.indexOf('.')) {return true;} // Protocol is defined before first dot (= absolute)
    return false; // Anything else must be relative
}

与简写形式和ES 6相同

// Traditional JS, shortened
function isUrlAbsolute(url) {
    return url.indexOf('//') === 0 ? true : url.indexOf('://') === -1 ? false : url.indexOf('.') === -1 ? false : url.indexOf('/') === -1 ? false : url.indexOf(':') > url.indexOf('/') ? false : url.indexOf('://') < url.indexOf('.') ? true : false;
}

// ES 6
const isUrlAbsolute = (url) => (url.indexOf('//') === 0 ? true : url.indexOf('://') === -1 ? false : url.indexOf('.') === -1 ? false : url.indexOf('/') === -1 ? false : url.indexOf(':') > url.indexOf('/') ? false : url.indexOf('://') < url.indexOf('.') ? true : false)

以下是一些测试案例:

// Test
console.log( isUrlAbsolute('http://stackoverflow.com') ) // -> true
console.log( isUrlAbsolute('//stackoverflow.com') ) // -> true
console.log( isUrlAbsolute('stackoverflow.com') ) // -> false
console.log( isUrlAbsolute('Ftp://example.net') ) // -> true
console.log( isUrlAbsolute('/redirect?target=http://example.org') ) // -> false
Philipp answered 2019-10-09T12:40:47Z
8 votes

如今,当许多服务使用协议相对URL(例如//cdn.example.com/libary.js)时,此方法更安全:

var isAbsolute = new RegExp('^([a-z]+://|//)', 'i');

if (isAbsolute.test(urlString)) {
  // go crazy here
}
rgtk answered 2019-10-09T12:41:15Z
7 votes

甚至更多符合RFC的通用URI方法:

^[a-z][a-z0-9+.-]*:正则表达式说明

对于诸如^[a-z][a-z0-9+.-]*:之类的链接,此处列出的其他解决方案将失败

RFC 3986将方案定义为:

^[a-z][a-z0-9+.-]*:

3.1。 方案[https://tools.ietf.org/html/rfc3986#section-3.1]

尽管相对协议的网址在技术上符合第4.2节的规定,但Paul Irish已转回另一种方式,并认为这是一种反模式。 参见[http://www.paulirish.com/2010/the-protocol-relative-url/]

4.2。 相对参考[http://tools.ietf.org/html/rfc3986#section-4.2]

如果您想要不使用协议相对URL的正则表达式:

^[a-z][a-z0-9+.-]*:

要查看其他类型的有效uri edge case的完整列表,请在此处查看列表:[https://en.wikipedia.org/wiki/URI_scheme]

Evan answered 2019-10-09T12:42:52Z
5 votes
var external = RegExp('^(https?:)?//');
if(external.test(el)){
    // do something
}

编辑:

使用下一个正则表达式,您甚至可以检查链接是指向同一域还是指向外部域:

var external = RegExp('^((f|ht)tps?:)?//(?!' + location.host + ')');
if(external.test(el)){
    // do something
}
davids answered 2019-10-09T12:43:28Z
4 votes

不要使用诸如regexp等低级的东西。这些东西已经被很多其他人解决了。 尤其是边缘情况。

看一下URI.js,它应该可以完成工作:[http://medialize.github.io/URI.js/docs.html#is]

var uri = new URI("http://example.org/");
uri.is("absolute") === true;
koppor answered 2019-10-09T12:44:02Z
1 votes
var adress = 'http://roflmao.com';
if (adress.substr(0,7) == 'http://' || adress.substr(0,8) == 'https://') {
    //
}
OptimusCrime answered 2019-10-09T12:44:25Z
1 votes

当超链接(即“ a”标签)上甚至发生点击时,如果该标签包含url是相对的或包含相同的主机,则将调用以下函数,如果该新页面包含不同的url,则该新页面将被加载到同一浏览器选项卡中,然后该页面将被加载 新的浏览器标签

jQuery(document).ready(function() {
    $('a').click(function(){

        var a = this;
        var a_href = $(this).attr('href');
        var regex = new RegExp('^(?:[a-z]+:)?//', 'i');     

        if(a.host == location.host || regex.test(a_href) == false){
            a.target = '_self';
        }else{
            a.target = '_blank';
        }
    }); 
});
Prajyot answered 2019-10-09T12:44:53Z
1 votes

这是解决问题的防弹方法:

让浏览器为我们处理一切。 不需要一些复杂/容易出错的正则表达式。

const isAbsoluteUrl = (url) => {
  const link = document.createElement('a');
  link.href = url;
  return link.origin + link.pathname + link.search + link.hash === url;
};
Etienne Martin answered 2019-10-09T12:45:28Z
-1 votes
var isExternalURL = url.toLowerCase().indexOf('http://') === 0 || url.toLowerCase().indexOf('https://') === 0 ;
rinjan answered 2019-10-09T12:45:49Z
translate from https://stackoverflow.com:/questions/10687099/how-to-test-if-a-url-string-is-absolute-or-relative