94

URLがJavascriptまたはjQueryの相対パスまたは絶対パスである場合、どうすればURLをテストできますか?渡されたURLがローカルパスであるか外部パスであるかに応じて、それに応じて処理したいと思います。

if (urlString starts with http:// or https://)
 //do this
4

16 に答える 16

199

速い

テストするだけでよい場合、または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

正規表現を説明する

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

^-文字列の
(?:始まり-キャプチャされていないグループの始まり
[a-z]+-「a」から「z」までの任意の文字を1回以上
:-文字列(コロン文字)
)?-キャプチャされていないグループの終わり。0回または1回出現するグループ
//-文字列(スラッシュ文字2文字)
'i'-大文字と小文字を区別しないフラグ

于 2013-10-31T14:57:07.580 に答える
39
var pat = /^https?:\/\//i;
if (pat.test(urlString))
{
    //do stuff
}

プロトコルの相対URLについては、次の正規表現を使用してください。

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

于 2012-05-21T14:27:00.213 に答える
28

元の回答

非常に高速で非常に柔軟なチェックは次のとおりです。

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

次の場合、これは絶対URLを認識します。

  • URLの最初の文字の後のどこかに「://」が含まれている、または
  • URLは「//」(プロトコル相対)で始まります

  • 正規表現はありません。
  • jQueryやその他の依存関係はありません。
  • 条件の大文字と小文字を区別するハードコードされたプロトコル名はありません。
  • 文字列操作なし(例:toLowerCaseなど)。
  • 「相対的または絶対的」をチェックするだけで、他の健全性チェックは行いません。WebURLまたは任意の内部プロトコルに使用できます。

アップデート1(全機能例)

指定されたURLに対してtrue/falseを返すクイック関数を次に示します。

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

ES6でも同じです。

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

アップデート2(URLパラメータ内のURL)

URLをフォーマットで追加アドレス指定するには、次の/redirect?target=http://example.orgコードを使用することをお勧めします。

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
}

そして、短い形式とES6でも同じです

// 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

アップデート3(相対URLを明確にする)

無効な出力に関するコメントをいくつか見てきました。

  • ソリューションはfalseを返しますlocalhost
  • 答えは失敗しますhttp:example.com

ただし、これらのURLは実際には相対URLです。テストは簡単です。

  1. ローカルホストのウェブルートにいくつかのフォルダを作成します。a/b/c/
  2. index.htmlファイルを作成し、次のリンクをそのファイルに配置します。<a href="localhost">test</a>
  3. ブラウザでインデックスページを開きます:http://localhost/a/b/c/index.htmlそしてリンクをクリックします。http:// localhost / a / b / c / localhostで終了します(http: // localhostでは終了しません)
  4. リンクhttp:example.comをindex.htmlファイルに配置するときにも同じことが起こります。http://example.comではなくhttp://localhost/a/b/c/example.comで終了します
于 2016-08-16T15:44:42.570 に答える
20

ニーズに応じて、これを判断するためのより信頼性の高い方法は、組み込みのURLインターフェイスを使用して、いくつかのURLオブジェクトを作成し、オリジンを比較することだと思います。

new URL(document.baseURI).origin === new URL(urlToTest, document.baseURI).origin;

これにより、ブラウザは、エッジケースの副作用を心配することなく、これらすべてを解析して把握することができます。

于 2019-07-15T22:12:40.393 に答える
18

正規表現を使用します。

if (/^(?:[a-z]+:)?\/\//i.test(url))
于 2012-05-21T14:25:49.200 に答える
12

さらにユニバーサルRFC準拠のURIアプローチ:

(?:^[a-z][a-z0-9+\.-]*:|\/\/) 正規表現の説明

ここにリストされている他のソリューションは、次のようなリンクでは失敗しますmailto:evan@nylas.com

RFC 3986は、スキームを次のように定義しています。

scheme = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )

3.1。スキーム https://www.rfc-editor.org/rfc/rfc3986#section-3.1

プロトコル相対URLはセクション4.2に従って技術的に有効ですが、Paul Irishは逆に振り返り、これをアンチパターンと見なしています。http://www.paulirish.com/2010/the-protocol-relative-url/を参照してください

4.2。相対リファレンス https://www.rfc-editor.org/rfc/rfc3986#section-4.2

プロトコル相対URLを使用せずに正規表現が必要な場合:

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

他のタイプの有効なURIエッジケースの完全なリストを確認するには、次のリストを確認してください:https ://en.wikipedia.org/wiki/URI_scheme

于 2015-08-13T15:00:20.020 に答える
10

現在、多くのサービスがプロトコル相対URL(例://cdn.example.com/libary.js)を使用している場合、この方法の方が安全です。

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

if (isAbsolute.test(urlString)) {
  // go crazy here
}
于 2013-10-30T19:23:22.193 に答える
8

正規表現などの低レベルのものは使用しないでください。これらのことは、他の多くの人々によって解決されています。特にエッジケース。

URI.jsを見てください、それは仕事をするはずです:http: //medialize.github.io/URI.js/docs.html#is

var uri = new URI("http://example.org/");
uri.is("absolute") === true;
于 2014-01-30T16:43:36.747 に答える
5

ブラウザ環境向けの非常に堅牢なソリューションは次のとおりです。

ブラウザにすべてを処理させます。複雑でエラーが発生しやすい正規表現は必要ありません。

const isAbsoluteUrl = (url) => {
  const link = document.createElement('a');
  link.href = url;
  return link.origin + link.pathname + link.search + link.hash === url;
};
于 2018-11-21T16:36:32.710 に答える
5

これを支援するために、try、catchブロックを使用できます。正規表現を使用する代わりに、すべてのステップでURLインターフェースを使用できます。

isExternalUrl (urlString) {
  try {
    const url = new URL(urlString) // THROW ON MISSING SCHEME

    // DOES THIS URL ORIGINATE FROM THIS WEBSITE?
    if (url.origin !== new URL(document.URL, document.baseURI).origin) {
      return true // IS EXTERNAL URL
    }
  } catch (_e) {
    // THROWS WHEN URL DOES NOT HAVE A SCHEME
    new URL(urlString, document.baseURL) // THROW AN EXCEPTION IF THE URL IS TRULY MALFORMED IN SOME WAY
  }

  return false
}
于 2020-08-12T10:34:46.377 に答える
4
var external = RegExp('^(https?:)?//');
if(external.test(el)){
    // do something
}

編集:

次の正規表現を使用すると、リンクが同じドメインに移動するのか、外部ドメインに移動するのかを確認することもできます。

var external = RegExp('^((f|ht)tps?:)?//(?!' + location.host + ')');
if(external.test(el)){
    // do something
}
于 2012-05-21T14:29:44.593 に答える
2
var adress = 'http://roflmao.com';
if (adress.substr(0,7) == 'http://' || adress.substr(0,8) == 'https://') {
    //
}
于 2012-05-21T14:27:58.977 に答える
2

上記の解決策はいずれもredirect_url、ハッカーが侵入したハッキン​​グを解決し/\/example.comませんでした/\\/example.com。これは、リダイレクトURLが相対的であるかどうかを判断するために私が思いついたものです。

var isRelative = !redirectUrl.match(/(\:|\/\\*\/)/);  // Don't allow "//" (with optional "\"'s) or ":"
于 2018-11-29T21:45:16.657 に答える
1

スラッシュまたはハッシュで開始するべきではありません。また、疑問符またはハッシュが前に付いていない場合は、二重スラッシュを含めるべきではありませんか?単一の正規表現では、「ダブルスラッシュなし」に一致させるのは非常に複雑になることをテストしません。

function test(s) {
    return s.charAt(0) != "#"
      && s.charAt(0) != "/"
      && ( s.indexOf("//") == -1 
        || s.indexOf("//") > s.indexOf("#")
        || s.indexOf("//") > s.indexOf("?")
    );
}

より簡単で、より明確で、より速くなります。

于 2012-05-14T19:19:15.733 に答える
0

次の関数は、ハイパーリンクでクリックイベントが発生したときに呼び出されます。つまり、タグに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';
        }
    }); 
});
于 2015-10-16T15:44:48.210 に答える
-1
var isExternalURL = url.toLowerCase().indexOf('http://') === 0 || url.toLowerCase().indexOf('https://') === 0 ;
于 2016-09-13T12:53:11.290 に答える