Periksa apakah string JavaScript adalah URL

284

Apakah ada cara dalam JavaScript untuk memeriksa apakah string adalah URL?

RegExes dikecualikan karena URL kemungkinan besar ditulis seperti stackoverflow; artinya mengatakan bahwa ia mungkin tidak memiliki .com, wwwatau http.

Bruno
sumber
22
Jika tidak ada http, per default tidak ada url.
nfechner
1
@nfechner yang mengatakan bahwa jika tidak menentukan protokol dan menggunakan karakter titik dua (lebih disukai dengan dua garis miring berikutnya) maka itu bukan URL?
jcolebrand
5
Seperti yang dapat Anda baca di URL RFC , satu-satunya bagian yang benar-benar diperlukan untuk membuat String menjadi URL yang valid adalah titik dua. URL yang valid terlihat seperti:<scheme>:<scheme-specific-part>
nfechner
8
Cara Anda menguji apakah sesuatu itu URL sangat bergantung pada konteks dan terlalu samar tanpa kualifikasi lebih lanjut. Apakah penting bagi Anda apakah itu sesuai dengan spesifikasi URL RFC, berfungsi saat melakukan panggilan sistem OS untuk membuka URL , diurai sebagai hrefelemen jangkar, berfungsi saat memanggil window.open(url), menunjuk ke sesuatu yang benar-benar ada, berfungsi di lokasi browser bar, atau kombinasi di atas? Anda akan mendapatkan jawaban yang sangat berbeda tergantung dari mana yang Anda pedulikan.
Roy Tinker

Jawaban:

189

Pertanyaan terkait dengan jawaban:

Pencocokan URL regex Javascript

Atau Regexp ini dari Devshed :

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);
}
Tom Gullen
sumber
1
Saya tahu tetapi saya sedang mencari di bookmark saya dan kebanyakan dari mereka ditulis seperti stackoverflow (tanpa .com, dll.)
Bruno
3
@Bruno: sangat mungkin bahwa mereka diselamatkan secara internal dengan judul dan URL yang terpisah, seperti { title: "Stackoverflow", uri: "http://stackoverflow.com" } Pembaruan: memang, lihat code.google.com/chrome/extensions/bookmarks.html
Marcel Korpel
10
mencoba menggunakan contoh Anda. Tetapi saya mendapatkan kesalahan pada pembakar yang mengatakan invalid quantifier. Ada ide?
Sisir
125
SyntaxError: Invalid regular expression: /^(https?://)?((([a-zd]([a-zd-]*[a-zd])*).)+[a-z]{2,}|((d{1,3}.){3}d{1,3}))(:d+)?(/[-a-zd%_.~+]*)*(?[;&a-zd%_.~+=-]*)?(#[-a-zd_]*)?$/: Invalid group Pengembalian fungsi: Google Chrome (Versi 30.0.1599.101) (Mac OS X: 10.8.5)
dr.dimitru
10
Ketahuilah bahwa jika Anda menggunakan string sebagai parameter untuk RegExpAnda harus menggandakan lolos dari garis miring terbalik - jika tidak, Anda akan mendapatkan kesalahan seperti grup yang tidak valid .
Kjell
165
function isURL(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);
}
Zemljoradnik
sumber
13
gagal untuk tautan gambar penelusuran google:http://www.google.com/url?sa=i&rct=j&q=&esrc=s&source=images&cd=&docid=nIv5rk2GyP3hXM&tbnid=isiOkMe3nCtexM:&ved=0CAUQjRw&url=http%3A%2F%2Fanimalcrossing.wikia.com%2Fwiki%2FLion&ei=ygZXU_2fGKbMsQTf4YLgAQ&bvm=bv.65177938,d.aWc&psig=AFQjCNEpBfKnal9kU7Zu4n7RnEt2nerN4g&ust=1398298682009707
bill davis
7
ini tidak bisa digunakan lambat
Hernán Eche
3
@ Hernáncheche Apa yang Anda maksud dengan lambat ? start = new Date(); isURL("http://michalstefanow.com"); end = new Date(); diff = end - start; console.log(diff)Saya memakai teko, pergi ke toilet, memanggil ibu saya dan hal itu dilakukan dalam waktu singkat ...
Mars Robertson
62
Ia kembali trueuntuk aaa.
alex naumov
1
Ini sama sekali bukan jawaban yang benar. Itu gagal banyak kasus uji dan yang lebih penting itu menggantung halaman Anda bahkan pada string pendek: isURL('12345678901234567890123')tambahkan beberapa karakter dan bahkan lebih buruk.
aamarks
142

Anda dapat mencoba menggunakan URLkonstruktor : jika tidak melempar, string adalah URL yang valid:

function isValidUrl(string) {
  try {
    new URL(string);
  } catch (_) {
    return false;  
  }

  return true;
}

Istilah 'URL' didefinisikan dalam RFC 3886 (sebagai URI); itu harus dimulai dengan nama skema, dan nama skema tidak terbatas pada http / https.

Contoh penting:

  • www.google.com bukan URL yang valid (skema yang hilang)
  • javascript:void(0) adalah URL yang valid, meskipun bukan HTTP
  • http://..adalah URL yang valid, dengan host tersebut ..; apakah itu terselesaikan tergantung pada DNS Anda
  • https://google..com URL yang valid, sama seperti di atas

Jika Anda ingin memeriksa apakah suatu string adalah URL HTTP yang valid:

function isValidHttpUrl(string) {
  let url;

  try {
    url = new URL(string);
  } catch (_) {
    return false;  
  }

  return url.protocol === "http:" || url.protocol === "https:";
}
Pavlo
sumber
13
@ AshD tidak, bukan; mis. Anda tidak dapat menggunakan sebagai hrefatribut untuk <a>. URL yang valid harus dimulai dengan nama skema , mis https://.
Pavlo
3
URL baru ('javascript: lansiran (23)')
blade091
6
@Plolo, ini mengembalikan trueisValidUrl("javascript:void(0)")
Praveena
3
Saya suka ini karena mengajari saya hal-hal baru tentang js! Tidak ada negatif palsu yang bisa saya temukan. Itu memang memiliki beberapa positif palsu: http://..Atauhttp:///a
aamarks
2
URL berfungsi mulai dari Edge sehingga semua yang ada di bawahnya mungkin tidak berfungsi seperti yang Anda harapkan. Pastikan Anda memeriksa kompatibilitasnya terlebih dahulu.
Tony T.
97

Daripada menggunakan ekspresi reguler, saya akan merekomendasikan menggunakan elemen anchor.

ketika Anda mengatur hrefproperti suatu anchor, berbagai properti lainnya diatur.

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"

sumber

Namun, jika nilainya hrefbukan url yang valid, maka nilai properti bantu tersebut akan menjadi string kosong.

Edit: seperti yang ditunjukkan dalam komentar: jika url yang tidak valid digunakan, properti dari URL saat ini dapat diganti.

Jadi, selama Anda tidak memasukkan URL halaman saat ini, Anda dapat melakukan sesuatu seperti:

function isValidURL(str) {
   var a  = document.createElement('a');
   a.href = str;
   return (a.host && a.host != window.location.host);
}
Luke
sumber
3
Ini bukan masalahnya (setidaknya di Chrome 48). Jika url yang diteruskan a.hreftidak valid, parser.hostkembalikan nama host halaman yang sedang Anda kunjungi, bukan yang diharapkan false.
Sam Beckham
2
Gah! itu aneh. Aku bersumpah aku menguji ini! Saya pikir itu adil untuk mengatakan bahwa ini tidak pernah benar-benar harus digunakan DI halaman saat ini, sehingga kondisional hanya dapat diubah. Saya akan mengedit posting.
Lukas
ini bukan kasus penggunaan yang sangat umum, tetapi teknik ini tidak berfungsi dalam konteks jendela browser Firefox (penting untuk pengembangan addon)
chrmod
@SamBeckham Ini pasti masalah ketika menggunakan metode ini, tapi saya hanya ingin menunjukkan bahwa ini bukan perilaku khusus. Jika Anda memiliki link pada halaman Anda yang valid, seperti <a href="invalidurl">, itu tidak pergi ke domain Anda. Itu akan ditambahkan ke akhir url saat ini. Jadi Chrome melakukan hal yang benar dengan memberi Anda nama host saat ini dari elemen "parser".
yts
4
function isValidURL(str): jauh lebih baik daripada menggunakan regex! Terima kasih!
Rodrigo
47

Saya menggunakan fungsi di bawah ini untuk memvalidasi URL dengan atau tanpa http/https:

function isValidURL(string) {
  var res = string.match(/(http(s)?:\/\/.)?(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/g);
  return (res !== null)
};

var testCase1 = "http://en.wikipedia.org/wiki/Procter_&_Gamble";
console.log(isValidURL(testCase1)); // return true

var testCase2 = "http://www.google.com/url?sa=i&rct=j&q=&esrc=s&source=images&cd=&docid=nIv5rk2GyP3hXM&tbnid=isiOkMe3nCtexM:&ved=0CAUQjRw&url=http%3A%2F%2Fanimalcrossing.wikia.com%2Fwiki%2FLion&ei=ygZXU_2fGKbMsQTf4YLgAQ&bvm=bv.65177938,d.aWc&psig=AFQjCNEpBfKnal9kU7Zu4n7RnEt2nerN4g&ust=1398298682009707";
console.log(isValidURL(testCase2)); // return true

var testCase3 = "https://sdfasd";
console.log(isValidURL(testCase3)); // return false

var testCase4 = "dfdsfdsfdfdsfsdfs";
console.log(isValidURL(testCase4)); // return false

var testCase5 = "magnet:?xt=urn:btih:123";
console.log(isValidURL(testCase5)); // return false

var testCase6 = "https://stackoverflow.com/";
console.log(isValidURL(testCase6)); // return true

var testCase7 = "https://w";
console.log(isValidURL(testCase7)); // return false

var testCase8 = "https://sdfasdp.ppppppppppp";
console.log(isValidURL(testCase8)); // return false

Vikasdeep Singh
sumber
2
Tampaknya solusi yang bagus! Bisakah Anda menambahkan beberapa tes yang menunjukkan itu berfungsi dalam beberapa kasus sudut (lihat misalnya komentar ini )?
Basj
@ Basj menambahkan kasus uji. Silakan periksa
Vikasdeep Singh
Lumayan, gagal melewatkan http: //⌘.ws atau 142.42.1.1 dan memungkinkan http: //.www.foo.bar./ tetapi tidak menggantung seperti beberapa regex lain termasuk jawaban berperingkat teratas.
aamarks
@ aamarks saya memeriksa jawaban Anda. Jawaban Anda gagal https://sdfasdp.pppppppppppyaitu kembali truetetapi pengembalian saya falseyang diharapkan saya pikir.
Vikasdeep Singh
4
itu mengembalikan true untuk [email protected]... bukan? Saya kira tidak seharusnya
Zohab Ali
35

Untuk Memvalidasi Url menggunakan javascript ditampilkan di bawah ini

function ValidURL(str) {
  var regex = /(http|https):\/\/(\w+:{0,1}\w*)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%!\-\/]))?/;
  if(!regex .test(str)) {
    alert("Please enter valid URL.");
    return false;
  } else {
    return true;
  }
}
kavitha Reddy
sumber
3
Beberapa bagian dari regex dapat sangat dikurangi: a) (http|https)menjadi (?:https?); b) :{0,1}untuk :?; c) [0-9]ke\d
Dmitry Parzhitsky
28

Andalkan perpustakaan: https://www.npmjs.com/package/valid-url

import { isWebUri } from 'valid-url';
// ...
if (!isWebUri(url)) {
    return "Not a valid url.";
}
Michael Bushe
sumber
yang ini memberi saya banyak masalah dengan url aneh yang sebenarnya diurai oleh browser, misalnya: memiliki {di url
Willyfrog
23

Peningkatan pada jawaban yang diterima ...

  • Periksa ftp / ftps sebagai protokol
  • Memiliki dua pelarian untuk backslash (\\)
  • Pastikan domain memiliki titik dan ekstensi (.com .io .xyz)
  • Mengizinkan titik dua penuh (:) di jalur misalnya http://thingiverse.com/download:1894343
  • Mengizinkan ampersand (&) di jalur, mis. Http://en.wikipedia.org/wiki/Procter_&_Gamble
  • Mengizinkan @ simbol di jalur, mis. Https://medium.com/@techytimo

    isURL(str) {
      var pattern = new RegExp('^((ft|htt)ps?:\\/\\/)?'+ // protocol
      '((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.)+[a-z]{2,}|'+ // domain name and extension
      '((\\d{1,3}\\.){3}\\d{1,3}))'+ // OR ip (v4) address
      '(\\:\\d+)?'+ // port
      '(\\/[-a-z\\d%@_.~+&:]*)*'+ // path
      '(\\?[;&a-z\\d%@_.,~+&:=-]*)?'+ // query string
      '(\\#[-a-z\\d_]*)?$','i'); // fragment locator
      return pattern.test(str);
    }
Mwirabua Tim
sumber
5
Tidak, itu seharusnya bukan jawaban yang diterima. Seperti beberapa yang lain, string itu hanya bergantung pada string karakter 33: isURL ('123456789012345678901234567890123') dan gagal dalam banyak uji kasus tepi: foo.com/blah_blah_(wikipedia)_(again) // salah mengembalikan salah.
aamarks
2
Itu karena localhost: 8080 bukan URL yang valid.
Shane
Seharusnya ftps: // localhost: 8080 =)
vp_arth
Tampaknya tidak berfungsi: hang pada input panjang (seperti @aanmarks berkata)
cecemel
13

Inilah metode lain.

var elm;
function isValidURL(u){
  if(!elm){
    elm = document.createElement('input');
    elm.setAttribute('type', 'url');
  }
  elm.value = u;
  return elm.validity.valid;
}

console.log(isValidURL('http://www.google.com/'));
console.log(isValidURL('//google.com'));
console.log(isValidURL('google.com'));
console.log(isValidURL('localhost:8000'));

Ryan Breece
sumber
Kode pendidikan! Mekanisme di sini mungkin identik dengan cara new URL(string)kerja kode Pavlo. Kedua tes memiliki hasil yang identik dengan semua kasus tepi yang saya uji. Saya suka kodenya karena lebih sederhana dan tidak melibatkan pembuatan elemen, tetapi kode Anda beberapa kali lebih cepat (mungkin karena tidak membuat el setelah penggunaan pertama).
aamarks
1
Terima kasih! Saya menerapkan saran Anda. Berhati-hatilah: Browser lama dan / atau perangkat seluler WebView mungkin belum mengimplementasikan elemen <input type = url>; dengan demikian nilai input akan diperlakukan seperti teks biasa (tidak ada validasi URL). REF: developer.mozilla.org/en-US/docs/Web/HTML/Element/input/url
Panini Luncher
10

(Saya tidak punya perwakilan untuk mengomentari ValidURL contoh ; oleh karena itu posting ini sebagai jawaban.)

Sementara penggunaan URL relatif protokol tidak dianjurkan ( URL Protocol-relatif ), mereka mendapatkan pekerjaan kadang-kadang. Untuk memvalidasi URL seperti itu dengan ekspresi reguler, bagian protokol bisa jadi opsional, misalnya:

function isValidURL(str) {
    var pattern = new RegExp('^((https?:)?\\/\\/)?'+ // protocol
        '(?:\\S+(?::\\S*)?@)?' + // authentication
        '((([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 locater
    if (!pattern.test(str)) {
        return false;
    } else {
        return true;
    }
}

Seperti yang dicatat orang lain, ekspresi reguler tampaknya bukan pendekatan yang paling cocok untuk memvalidasi URL.

ko la
sumber
Saya pikir pada awalnya ini cukup bagus tetapi gagal banyak tes di mathiasbynens.be/demo/url-regex , dan kemudian hang onisValidURL("https://[email protected]/13176")
aamarks
Ya, seperti yang saya katakan, saya hanya berkomentar di bagian protokol. Saya menambahkan klausa otentikasi untuk ditangani @. Itu tidak menggantung di browser saya .
ko la
Maaf, saya sedang melalui beberapa di antaranya untuk mengevaluasinya dan melewatkan bahwa jawaban Anda mengomentari jawaban yang diberikan. Saya pikir koreksi Anda bahkan membantu saya memulai ini ketika saya pertama kali mengunjungi halaman ini. Jangan digantung sekarang.
aamarks
9

Anda dapat menggunakan API asli URL :

  const isUrl = string => {
      try { return Boolean(new URL(string)); }
      catch(e){ return false; }
  }
Aral Roca
sumber
3
Tampak sangat mirip dengan jawaban yang diberikan oleh @pavlo, hanya nama variabel yang diubah;)
Munim Munna
2
harus benar-benar ada metode asli yang sederhana untuk memeriksa ini sekarang - jawaban ini tampak sangat menjanjikan tetapi mengembalikan benar awal seperti @Basj disebutkan di atas.
zero_cool
8

Seperti yang telah dicatat, regex sempurna sulit dipahami tetapi tampaknya masih merupakan pendekatan yang masuk akal (alternatifnya adalah tes sisi server atau API URL eksperimental baru ). Namun, jawaban dengan peringkat tinggi sering kali kembali palsu untuk URL umum, tetapi lebih buruk lagi akan membekukan aplikasi / halaman Anda selama beberapa menit bahkan dengan string sederhana isURL('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'). Sudah ditunjukkan di beberapa komentar, tetapi kemungkinan besar belum memasukkan nilai buruk untuk melihatnya. Tergantung seperti itu membuat kode itu tidak dapat digunakan dalam aplikasi serius apa pun. Saya pikir itu karena set kasus sensitif ulang kode seperti ((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.?)+[a-z]{2,}|' .... Keluarkan 'i' dan itu tidak menggantung tetapi tentu saja tidak akan berfungsi seperti yang diinginkan. Tetapi bahkan dengan flag abaikan pengujian tersebut menolak nilai unicode tinggi yang diizinkan.

Yang terbaik yang telah disebutkan adalah:

function isURL(str) {
  return /^(?:\w+:)?\/\/([^\s\.]+\.\S{2}|localhost[\:?\d]*)\S*$/.test(str); 
}

Itu berasal dari Github segmentio / is-url . Hal yang baik tentang repositori kode adalah Anda dapat melihat pengujian dan masalah apa pun dan juga string pengujian yang menjalankannya. Ada cabang yang akan memungkinkan string protokol yang hilang seperti google.com, meskipun Anda mungkin membuat terlalu banyak asumsi saat itu. Repositori telah diperbarui dan saya tidak berencana mencoba menjaga mirror di sini. Ini telah dipecah menjadi beberapa tes terpisah untuk menghindari reduksi RegEx yang dapat dieksploitasi untuk serangan DOS (saya tidak berpikir Anda harus khawatir tentang itu dengan sisi klien, tetapi Anda harus khawatir tentang halaman Anda menggantung begitu lama sehingga Anda pengunjung meninggalkan situs Anda).

Ada satu repositori lain yang pernah saya lihat yang bahkan mungkin lebih baik untuk isURL di dperini / regex-weburl.js , tetapi ini sangat kompleks. Ini memiliki daftar tes yang lebih besar dari URL yang valid dan tidak valid. Yang sederhana di atas masih melewati semua positif dan hanya gagal untuk memblokir beberapa negatif aneh seperti http://a.b--c.de/ips khusus.

Apa pun yang Anda pilih, jalankan melalui fungsi ini yang telah saya adaptasi dari tes di dperini / regex-weburl.js, saat menggunakan inpector Alat Pengembang browser Anda.

function testIsURL() {
//should match
console.assert(isURL("http://foo.com/blah_blah"));
console.assert(isURL("http://foo.com/blah_blah/"));
console.assert(isURL("http://foo.com/blah_blah_(wikipedia)"));
console.assert(isURL("http://foo.com/blah_blah_(wikipedia)_(again)"));
console.assert(isURL("http://www.example.com/wpstyle/?p=364"));
console.assert(isURL("https://www.example.com/foo/?bar=baz&inga=42&quux"));
console.assert(isURL("http://✪df.ws/123"));
console.assert(isURL("http://userid:[email protected]:8080"));
console.assert(isURL("http://userid:[email protected]:8080/"));
console.assert(isURL("http://[email protected]"));
console.assert(isURL("http://[email protected]/"));
console.assert(isURL("http://[email protected]:8080"));
console.assert(isURL("http://[email protected]:8080/"));
console.assert(isURL("http://userid:[email protected]"));
console.assert(isURL("http://userid:[email protected]/"));
console.assert(isURL("http://142.42.1.1/"));
console.assert(isURL("http://142.42.1.1:8080/"));
console.assert(isURL("http://➡.ws/䨹"));
console.assert(isURL("http://⌘.ws"));
console.assert(isURL("http://⌘.ws/"));
console.assert(isURL("http://foo.com/blah_(wikipedia)#cite-1"));
console.assert(isURL("http://foo.com/blah_(wikipedia)_blah#cite-1"));
console.assert(isURL("http://foo.com/unicode_(✪)_in_parens"));
console.assert(isURL("http://foo.com/(something)?after=parens"));
console.assert(isURL("http://☺.damowmow.com/"));
console.assert(isURL("http://code.google.com/events/#&product=browser"));
console.assert(isURL("http://j.mp"));
console.assert(isURL("ftp://foo.bar/baz"));
console.assert(isURL("http://foo.bar/?q=Test%20URL-encoded%20stuff"));
console.assert(isURL("http://مثال.إختبار"));
console.assert(isURL("http://例子.测试"));
console.assert(isURL("http://उदाहरण.परीक्षा"));
console.assert(isURL("http://-.~_!$&'()*+,;=:%40:80%2f::::::@example.com"));
console.assert(isURL("http://1337.net"));
console.assert(isURL("http://a.b-c.de"));
console.assert(isURL("http://223.255.255.254"));
console.assert(isURL("postgres://u:[email protected]:5702/db"));
console.assert(isURL("https://[email protected]/13176"));

//SHOULD NOT MATCH:
console.assert(!isURL("http://"));
console.assert(!isURL("http://."));
console.assert(!isURL("http://.."));
console.assert(!isURL("http://../"));
console.assert(!isURL("http://?"));
console.assert(!isURL("http://??"));
console.assert(!isURL("http://??/"));
console.assert(!isURL("http://#"));
console.assert(!isURL("http://##"));
console.assert(!isURL("http://##/"));
console.assert(!isURL("http://foo.bar?q=Spaces should be encoded"));
console.assert(!isURL("//"));
console.assert(!isURL("//a"));
console.assert(!isURL("///a"));
console.assert(!isURL("///"));
console.assert(!isURL("http:///a"));
console.assert(!isURL("foo.com"));
console.assert(!isURL("rdar://1234"));
console.assert(!isURL("h://test"));
console.assert(!isURL("http:// shouldfail.com"));
console.assert(!isURL(":// should fail"));
console.assert(!isURL("http://foo.bar/foo(bar)baz quux"));
console.assert(!isURL("ftps://foo.bar/"));
console.assert(!isURL("http://-error-.invalid/"));
console.assert(!isURL("http://a.b--c.de/"));
console.assert(!isURL("http://-a.b.co"));
console.assert(!isURL("http://a.b-.co"));
console.assert(!isURL("http://0.0.0.0"));
console.assert(!isURL("http://10.1.1.0"));
console.assert(!isURL("http://10.1.1.255"));
console.assert(!isURL("http://224.1.1.1"));
console.assert(!isURL("http://1.1.1.1.1"));
console.assert(!isURL("http://123.123.123"));
console.assert(!isURL("http://3628126748"));
console.assert(!isURL("http://.www.foo.bar/"));
console.assert(!isURL("http://www.foo.bar./"));
console.assert(!isURL("http://.www.foo.bar./"));
console.assert(!isURL("http://10.1.1.1"));}

Dan kemudian uji string 'a's.

Lihat perbandingan regex isURL ini oleh Mathias Bynens untuk info lebih lanjut sebelum Anda memposting regex yang tampaknya hebat.

aamarks
sumber
Saya memeriksa jawaban Anda. Jawaban Anda gagal untuk sdfasdp.ppppppppppp yaitu mengembalikan benar tetapi diharapkan salah
Vikasdeep Singh
1
Saya pikir itu URL yang valid, secara struktural. Bukan ahli tentang standar tetapi saya tidak berpikir ada batas pada panjang bagian .com (saya tahu .online sah).
aamarks
1
Saya hampir tidak tahu bagaimana menulis regex beberapa bulan yang lalu. Masalahnya parah. Kedua regex yang saya kutip dapat menyelesaikan isURL('a'.repeat(100))jutaan kali / detik (yang lebih kompleks dari dperini sebenarnya lebih cepat). Beberapa jawaban peringkat tinggi dari formulir ([a-zA-Z] +) * akan membutuhkan waktu berjam-jam untuk menyelesaikannya sekali. Cari ulang RegEx untuk informasi lebih lanjut.
aamarks
6

Saya tidak dapat mengomentari pos yang paling dekat # 5717133 , tetapi di bawah ini adalah cara saya menemukan cara agar @ tom-gullen regex berfungsi.

/^(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
iamnewton
sumber
2
Ini bekerja untuk saya, tetapi saya perlu backslash backslash. var pattern = new 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');
Fernando Chavez Herrera
Lihat w3resource.com/javascript-exercises/... untuk kasus uji lebih lanjut
Kewal Shah
5

Gunakan validator.js

ES6

import isURL from 'validator/lib/isURL'

isURL(string)

Tidak ada ES6

var validator = require('validator');

validator.isURL(string)

Anda juga dapat memperbaiki perilaku fungsi ini dengan meneruskan optionsobjek opsional sebagai argumen keduaisURL

Ini adalah optionsobjek default :

let options = {
    protocols: [
        'http',
        'https',
        'ftp'
    ],
    require_tld: true,
    require_protocol: false,
    require_host: true,
    require_valid_protocol: true,
    allow_underscores: false,
    host_whitelist: false,
    host_blacklist: false,
    allow_trailing_dot: false,
    allow_protocol_relative_urls: false,
    disallow_auth: false
}

isURL(string, options)

host_whitelistdan host_blacklistbisa berupa array host. Mereka juga mendukung ekspresi reguler.

let options = {
    host_blacklist: ['foo.com', 'bar.com'],
}

isURL('http://foobar.com', options) // => true
isURL('http://foo.bar.com/', options) // => true
isURL('http://qux.com', options) // => true

isURL('http://bar.com/', options) // => false
isURL('http://foo.com/', options) // => false


options = {
    host_blacklist: ['bar.com', 'foo.com', /\.foo\.com$/],
}

isURL('http://foobar.com', options) // => true
isURL('http://foo.bar.com/', options) // => true
isURL('http://qux.com', options) // => true

isURL('http://bar.com/', options) // => false
isURL('http://foo.com/', options) // => false
isURL('http://images.foo.com/', options) // => false
isURL('http://cdn.foo.com/', options) // => false
isURL('http://a.b.c.foo.com/', options) // => false
Ilyich
sumber
1
Bagus! Perpustakaan kecil (kurang dari 40k yang diperkecil), perpustakaan populer (lebih dari 3M unduhan mingguan di npm), memberi Anda banyak fleksibilitas dalam menentukan validitas URL untuk kasus penggunaan khusus Anda, dan memiliki sejumlah validator lain selain URL. Sejauh ini, inilah jawaban terbaik, IMHO.
Javid Jamae
4

Salah satu fungsi yang telah saya gunakan untuk memvalidasi URL "string" adalah:

var matcher = /^(?:\w+:)?\/\/([^\s\.]+\.\S{2}|localhost[\:?\d]*)\S*$/;

function isUrl(string){
  return matcher.test(string);
}

Fungsi ini akan mengembalikan boolean apakah string adalah URL.

Contoh:

isUrl("https://google.com");     // true
isUrl("http://google.com");      // true
isUrl("http://google.de");       // true
isUrl("//google.de");            // true
isUrl("google.de");              // false
isUrl("http://google.com");      // true
isUrl("http://localhost");       // true
isUrl("https://sdfasd");         // false
Chris
sumber
4

Ini cukup sulit dilakukan dengan regex murni karena URL memiliki banyak 'ketidaknyamanan'.

  1. Misalnya nama domain memiliki batasan rumit pada tanda hubung:

    Sebuah. Diijinkan memiliki banyak tanda hubung berturut-turut di tengah.

    b. tetapi karakter pertama dan karakter terakhir dari nama domain tidak boleh berupa tanda hubung

    c. Karakter ke-3 dan ke-4 tidak boleh berupa tanda hubung

  2. Demikian pula nomor port hanya bisa di kisaran 1-65535. Ini mudah untuk memeriksa apakah Anda mengekstrak bagian port dan mengubahnya, inttetapi cukup sulit untuk memeriksa dengan ekspresi reguler.

  3. Juga tidak ada cara mudah untuk memeriksa ekstensi domain yang valid. Beberapa negara memiliki domain tingkat kedua (seperti 'co.uk'), atau ekstensi dapat berupa kata yang panjang seperti '.international'. Dan TLD baru ditambahkan secara teratur. Jenis-jenis hal ini hanya dapat diperiksa terhadap daftar kode-keras. (lihat https://en.wikipedia.org/wiki/Top-level_domain )

  4. Lalu ada url magnet, alamat ftp dll. Semua ini memiliki persyaratan yang berbeda.

Namun demikian, berikut adalah fungsi yang menangani hampir semua hal kecuali:

  • Kasus 1. c
  • Menerima nomor port 1-5 digit
  • Menerima ekstensi 2-13 karakter apa pun
  • Tidak menerima ftp, magnet, dll ...

function isValidURL(input) {
    pattern = '^(https?:\\/\\/)?' + // protocol
        '((([a-zA-Z\\d]([a-zA-Z\\d-]{0,61}[a-zA-Z\\d])*\\.)+' + // sub-domain + domain name
        '[a-zA-Z]{2,13})' + // extension
        '|((\\d{1,3}\\.){3}\\d{1,3})' + // OR ip (v4) address
        '|localhost)' + // OR localhost
        '(\\:\\d{1,5})?' + // port
        '(\\/[a-zA-Z\\&\\d%_.~+-:@]*)*' + // path
        '(\\?[a-zA-Z\\&\\d%_.,~+-:@=;&]*)?' + // query string
        '(\\#[-a-zA-Z&\\d_]*)?$'; // fragment locator
    regex = new RegExp(pattern);
    return regex.test(input);
}

let tests = [];
tests.push(['', false]);
tests.push(['http://en.wikipedia.org/wiki/Procter_&_Gamble', true]);
tests.push(['https://sdfasd', false]);
tests.push(['http://www.google.com/url?sa=i&rct=j&q=&esrc=s&source=images&cd=&docid=nIv5rk2GyP3hXM&tbnid=isiOkMe3nCtexM:&ved=0CAUQjRw&url=http%3A%2F%2Fanimalcrossing.wikia.com%2Fwiki%2FLion&ei=ygZXU_2fGKbMsQTf4YLgAQ&bvm=bv.65177938,d.aWc&psig=AFQjCNEpBfKnal9kU7Zu4n7RnEt2nerN4g&ust=1398298682009707', true]);
tests.push(['https://stackoverflow.com/', true]);
tests.push(['https://w', false]);
tests.push(['aaa', false]);
tests.push(['aaaa', false]);
tests.push(['oh.my', true]);
tests.push(['dfdsfdsfdfdsfsdfs', false]);
tests.push(['google.co.uk', true]);
tests.push(['test-domain.MUSEUM', true]);
tests.push(['-hyphen-start.gov.tr', false]);
tests.push(['hyphen-end-.com', false]);
tests.push(['https://sdfasdp.international', true]);
tests.push(['https://sdfasdp.pppppppp', false]);
tests.push(['https://sdfasdp.ppppppppppppppppppp', false]);
tests.push(['https://sdfasd', false]);
tests.push(['https://sub1.1234.sub3.sub4.sub5.co.uk/?', true]);
tests.push(['http://www.google-com.123', false]);
tests.push(['http://my--testdomain.com', false]);
tests.push(['http://my2nd--testdomain.com', true]);
tests.push(['http://thingiverse.com/download:1894343', true]);
tests.push(['https://medium.com/@techytimo', true]);
tests.push(['http://localhost', true]);
tests.push(['localhost', true]);
tests.push(['localhost:8080', true]);
tests.push(['localhost:65536', true]);
tests.push(['localhost:80000', false]);
tests.push(['magnet:?xt=urn:btih:123', true]);

for (let i = 0; i < tests.length; i++) {
    console.log('Test #' + i + (isValidURL(tests[i][0]) == tests[i][1] ? ' passed' : ' failed') + ' on ["' + tests[i][0] + '", ' + tests[i][1] + ']');
}

Caner
sumber
1

Saya pikir menggunakan API URL asli lebih baik daripada pola regex kompleks seperti yang disarankan @pavlo. Ini memiliki beberapa kelemahan yang dapat kita perbaiki dengan beberapa kode tambahan. Pendekatan ini gagal untuk url yang valid berikut.

//cdn.google.com/script.js

Kita dapat menambahkan protokol yang hilang sebelumnya untuk menghindari itu. Juga gagal mendeteksi url berikut yang tidak valid.

http://w
http://..

Jadi mengapa memeriksa seluruh url? kita cukup memeriksa domainnya. Saya meminjam regex untuk memverifikasi domain dari sini .

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;
    }
}

The hostnameatribut string kosong untuk javascript:void(0), sehingga bekerja untuk itu juga, dan Anda juga dapat menambahkan alamat IP verifier juga. Saya ingin tetap menggunakan API asli, dan berharap itu mulai mendukung semuanya dalam waktu dekat.

Munim Munna
sumber
Menarik, tetapi mungkin masih perlu bekerja pada regex karena sekarang memperkenalkan negatif palsu yang new URLtidak ada dalam tes yang saya lakukan. Ini memanggil: http://142.42.1.1 //falsedan memblokir string unicode tinggi.
aamarks
1

Pertanyaannya menanyakan metode validasi untuk url seperti stackoverflow , tanpa protokol atau titik apa pun di nama host. Jadi, ini bukan masalah memvalidasi sintaks url, tetapi memeriksa apakah itu url yang valid, dengan benar-benar memanggilnya.

Saya mencoba beberapa metode untuk mengetahui apakah url benar ada dan dapat dipanggil dari dalam browser, tetapi tidak menemukan cara untuk menguji dengan javascript header respons panggilan:

  • menambahkan elemen jangkar baik-baik saja untuk menembakkan click()metode.
  • membuat panggilan ajax ke url yang menantang dengan 'GET'baik-baik saja, tetapi memiliki berbagai keterbatasan karena CORSkebijakan dan itu bukan kasus menggunakan ajax, karena sebagai url mungkin ada di luar domain server saya.
  • menggunakan fetch API memiliki solusi yang mirip dengan ajax.
  • masalah lain adalah bahwa saya memiliki server saya di bawah httpsprotokol dan melempar pengecualian saat memanggil url tidak aman.

Jadi, solusi terbaik yang dapat saya pikirkan adalah mendapatkan beberapa alat untuk melakukan CURLmenggunakan javascript mencoba sesuatu seperti curl -I <url>. Sayangnya saya tidak menemukan apa pun dan sepertinya itu tidak mungkin. Saya akan menghargai komentar Anda tentang ini.

Tetapi, pada akhirnya, saya memiliki server yang berjalan PHP dan karena saya menggunakan Ajax untuk hampir semua permintaan saya, saya menulis sebuah fungsi di sisi server untuk melakukan permintaan ikal di sana dan kembali ke browser.

Mengenai url kata tunggal pada pertanyaan 'stackoverflow' itu akan membawa saya ke https://daniserver.com.ar/stackoverflow, di mana daniserver.com.ar adalah domain saya sendiri.

Daniel Faure
sumber
OP mungkin seharusnya mengindikasikan lebih dari apa maksudnya. Masalahnya tentu bervariasi pada kebutuhan Anda dan apakah lebih penting untuk mengecualikan positif palsu atau memasukkan negatif palsu. Seperti masalah yang dinyatakan sepertinya tidak ada jawaban untuk saya. Bisakah Anda benar-benar mengambil foodan menganggap itu http atau https atau .com atau .es atau salah satu sufiks yang tak terhitung jumlahnya? Apakah Anda terus melemparkan wastafel dapur sampai Anda mendapatkan yang benar?
aamarks
1

Ini tampaknya menjadi salah satu masalah tersulit dalam CS;)

Berikut ini adalah solusi tidak lengkap lainnya yang berfungsi cukup baik untuk saya dan lebih baik daripada yang lain yang saya lihat di sini. Saya menggunakan input [type = url] untuk ini untuk mendukung IE11, jika tidak akan jauh lebih mudah menggunakan window.URL untuk melakukan validasi sebagai gantinya:

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:[email protected]'),
  validateUrl('https://google.com'),
  validateUrl('100.100.100.100/abc'),
  validateUrl('100.100.100.256/abc')); // false

Untuk menerima input yang tidak lengkap seperti "www.mydomain.com" itu juga akan membuatnya valid dengan asumsi protokol adalah "http" dalam kasus-kasus tersebut dan mengembalikan URL yang valid jika alamat itu valid. Ini mengembalikan false ketika tidak valid.

Ini juga mendukung domain IPv4, tetapi tidak IPv6.

rosenfeld
sumber
1

Dalam kasus saya, satu-satunya persyaratan saya adalah bahwa input pengguna tidak akan diartikan sebagai tautan relatif ketika ditempatkan di href dari sebuah tag dan jawaban di sini adalah sedikit OTT untuk itu atau URL yang diizinkan tidak memenuhi persyaratan saya, jadi ini adalah apa yang akan saya ikuti:

^https?://.+$

Hal yang sama dapat dicapai dengan mudah tanpa regex.

rans
sumber
1

ini bekerja dengan saya

function isURL(str) {
  var regex = /(http|https):\/\/(\w+:{0,1}\w*)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%!\-\/]))?/;
  var pattern = new RegExp(regex); 
return pattern.test(str);
}
HeshamSalama
sumber
1
Jawaban ini sudah diberikan di atas 4 tahun yang lalu oleh kavitha Reddy.
aamarks
saya hanya membuatnya lebih sederhana dan abstrak
HeshamSalama
1

Jika Anda dapat mengubah jenis input, saya pikir solusi ini akan jauh lebih mudah:

Anda dapat menggunakan sederhana type="url"dalam input Anda dan periksa dengan checkValidity()di js

Misalnya:

your.html

<input id="foo" type="url">

milikmu

// The selector is JQuery, but the function is plain JS
$("#foo").on("keyup", function() {
    if (this.checkValidity()) {
        // The url is valid
    } else {
        // The url is invalid
    }
});
Daniel Rodríguez
sumber
1

Ini jelas bukan pendekatan yang paling efektif, tetapi mudah dibaca dan mudah dibentuk untuk apa pun yang Anda butuhkan. Dan lebih mudah untuk menambahkan regex / kompleksitas dari sini. Jadi, inilah pendekatan yang sangat pragmatis

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;
}

UJI:

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);
        });
    });
});

sumber
1

Mathias Bynens telah menyusun daftar regex URL yang terkenal dengan URL uji. Ada sedikit alasan untuk menulis ungkapan reguler baru; pilih saja yang sudah ada yang paling cocok untuk Anda.

Tetapi tabel perbandingan untuk regex tersebut juga menunjukkan bahwa hampir tidak mungkin untuk melakukan validasi URL dengan satu ekspresi reguler. Semua regex dalam daftar Bynens menghasilkan false positive dan false negative.

Saya sarankan Anda menggunakan parser URL yang ada (misalnya new URL('http://www.example.com/')dalam JavaScript) dan kemudian menerapkan pemeriksaan yang ingin Anda lakukan terhadap bentuk URL resp yang diuraikan dan dinormalisasi. komponennya. Menggunakan URLantarmuka JavaScript memiliki manfaat tambahan karena hanya akan menerima URL yang benar-benar diterima oleh browser.

Anda juga harus ingat bahwa URL yang secara teknis salah mungkin masih berfungsi. Sebagai contoh http://w_w_w.example.com/, http://www..example.com/, http://123.example.com/semua memiliki bagian hostname tidak valid tapi setiap browser saya tahu akan mencoba untuk membuka mereka tanpa keluhan, dan ketika Anda menentukan alamat IP untuk nama-nama tidak valid dalam /etc/hosts/URL tersebut bahkan akan bekerja tetapi hanya pada komputer Anda.

Karena itu, pertanyaannya adalah bukan apakah URL itu valid, melainkan URL mana yang berfungsi dan harus diizinkan dalam konteks tertentu.

Jika Anda ingin melakukan validasi URL, ada banyak detail dan kasus tepi yang mudah diabaikan:

  • URL dapat berisi kredensial seperti pada http://user:[email protected]/.
  • Nomor port harus dalam kisaran 0-65535, tetapi Anda mungkin masih ingin mengecualikan port wildcard 0.
  • Nomor port mungkin memiliki nol di depan seperti di http://www.example.com:000080/ .
  • Alamat IPv4 sama sekali tidak terbatas pada 4 bilangan bulat desimal di kisaran 0-255. Anda dapat menggunakan satu hingga empat bilangan bulat, dan bilangan desimal, oktal, atau heksadesimal. URL https: //010.010.000010.010/ , https: //0x8.0x8.0x0008.0x8/ , https: //8.8.2056/ , https: //8.526344/ , https: // 134744072 / semuanya valid dan hanya cara kreatif menulis https://8.8.8.8/ .
  • Mengizinkan alamat loopback ( http://127.0.0.1/ ), alamat IP pribadi ( http://192.168.1.1 ), alamat tautan-lokal ( http://169.254.100.200 ) dan sebagainya dapat berdampak pada keamanan atau pribadi. Jika, misalnya, Anda mengizinkannya sebagai alamat avatar pengguna di suatu forum, Anda menyebabkan browser pengguna mengirimkan permintaan jaringan yang tidak diminta di jaringan lokal mereka dan di internet hal-hal seperti permintaan dapat menyebabkan hal-hal yang lucu dan tidak begitu lucu. terjadi di rumahmu.
  • Untuk alasan yang sama, Anda mungkin ingin membuang tautan ke nama host yang tidak sepenuhnya memenuhi syarat, dengan kata lain nama host tanpa titik.
  • Tetapi nama host mungkin selalu memiliki trailing dot (seperti di http://www.stackoverflow.com.).
  • Bagian hostname dari suatu tautan dapat berisi tanda kurung sudut untuk alamat IPv6 seperti pada http: // [:: 1] .
  • Alamat IPv6 juga memiliki rentang untuk jaringan pribadi atau alamat tautan-lokal, dll.
  • Jika Anda memblokir alamat IPv4 tertentu, ingatlah bahwa misalnya https://127.0.0.1 dan https: // [:: ffff: 127.0.0.1] arahkan ke sumber daya yang sama (jika perangkat loopback mesin Anda siap IPv6) ).
  • Bagian hostname dari URL sekarang mungkin berisi Unicode, sehingga rentang karakter [-0-9a-zA-z]sudah pasti tidak lagi memadai.
  • Banyak pendaftar untuk domain tingkat atas menentukan batasan spesifik, misalnya pada set karakter Unicode yang diizinkan. Atau mereka membagi ruang nama mereka (seperti co.ukdan banyak lainnya).
  • Domain tingkat atas tidak boleh mengandung angka desimal, dan tanda hubung tidak diizinkan kecuali untuk awalan A-label IDN "xn--".
  • Domain tingkat atas Unicode (dan enkode kode punycode dengan "xn--") masih harus hanya berisi huruf, tetapi siapa yang ingin memeriksanya dalam regex?

Yang mana dari batasan dan aturan ini yang berlaku adalah pertanyaan tentang persyaratan dan selera proyek.

Baru-baru ini saya menulis validator URL untuk aplikasi web yang cocok untuk URL yang disediakan pengguna di forum, jejaring sosial, atau sejenisnya. Jangan ragu untuk menggunakannya sebagai basis untuk basis Anda sendiri:

Saya juga telah menulis posting blog The Gory Details of Validasi URL dengan informasi lebih mendalam.

Guido Flohr
sumber
1

Saya mengubah fungsi untuk mencocokkan + membuat perubahan di sini dengan garis miring dan kerjanya: (http: // dan https) keduanya

function isValidUrl(userInput) {
    var res = userInput.match(/(http(s)?:\/\/.)?(www\.)?[-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,6}\b([-a-zA-Z0-9@:%_\+.~#?&//=]*)/g);
    if(res == null)
       return false;
    else
       return true;
}
Ashish Gupta
sumber
0

Berikut ini hanya pemeriksaan yang sangat sederhana untuk memastikan ada protokol yang valid, dan ekstensi domain harus dua atau lebih karakter.

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
    );

};
Michael Ecklund
sumber
0

Jika Anda juga perlu mendukung https://localhost:3000maka gunakan versi modifikasi dari [Devshed] ini.

    function isURL(url) {
        if(!url) return false;
        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
            'localhost' + // OR localhost
            '(\\:\\d+)?(\\/[-a-z\\d%_.~+]*)*'+ // port and path
            '(\\?[;&a-z\\d%_.~+=-]*)?'+ // query string
            '(\\#[-a-z\\d_]*)?$', 'i'); // fragment locator
        return pattern.test(url);
    }
Mark Hetherington
sumber
0

Ada beberapa tes menggunakan konstruktor URL yang tidak menggambarkan apakah inputnya berupa string atau objek 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;  
    }
}
greg.arnott
sumber
0

Pembaruan 2020. Untuk memperluas jawaban answerd baik dari @iamnewton dan @Fernando Chavez Herrera, saya mulai melihat @sedang digunakan di jalur URL.

Jadi regex yang diperbarui adalah:

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');

Jika Anda ingin mengizinkannya dalam string kueri dan hash, gunakan:

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');

Yang sedang berkata, saya tidak yakin apakah ada aturan whitepaper melarang @dalam string kueri atau hash.

Janus
sumber
0

Sudah ada banyak jawaban, tetapi inilah kontribusi lain: Diambil langsung dari URLpemeriksaan validitas polyfill, gunakan inputelemen dengan type="url"untuk mengambil keuntungan dari pemeriksaan validitas bawaan browser:

var inputElement = doc.createElement('input');
inputElement.type = 'url';
inputElement.value = url;

if (!inputElement.checkValidity()) {
    throw new TypeError('Invalid URL');
}

Sumber

Bruno Finger
sumber