Kiểm tra xem chuỗi JavaScript có phải là URL không


283

Có cách nào trong JavaScript để kiểm tra xem một chuỗi có phải là URL không?

RegExes bị loại trừ vì URL rất có thể được viết như stackoverflow; điều đó có nghĩa là nó có thể không có .com, wwwhoặc http.


22
Nếu nó bị thiếu http, nó là mặc định không có url.
nfechner

1
@nfechner có nghĩa là nếu nó không chỉ định giao thức và sử dụng ký tự dấu hai chấm (tốt nhất là có hai dấu gạch chéo tiếp theo) thì đó có phải là URL không?
jcolebrand

5
Như bạn có thể đọc trong RFC URL , phần duy nhất thực sự không cần thiết để tạo Chuỗi thành URL hợp lệ là dấu hai chấm. Các URL hợp lệ trông giống như:<scheme>:<scheme-specific-part>
nfechner


8
Làm thế nào bạn kiểm tra xem một cái gì đó là một URL là rất bối cảnh phụ thuộc và quá mơ hồ mà không cần trình độ chuyên môn hơn nữa. Việc bạn có tuân thủ thông số RFC của URL hay không, có hoạt động khi thực hiện lệnh gọi hệ điều hành để mở URL , phân tích cú pháp hreftrong phần tử neo, hoạt động khi gọi window.open(url), trỏ đến thứ gì đó thực sự tồn tại, hoạt động ở vị trí trình duyệt thanh, hoặc một sự kết hợp của ở trên? Bạn sẽ nhận được câu trả lời rất khác nhau tùy thuộc vào câu hỏi nào bạn quan tâm.
Roy Tinker

Câu trả lời:


189

Một câu hỏi liên quan với một câu trả lời:

Kết hợp URL regex Javascript

Hoặc Regrec từ Devshed này :

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

1
Tôi biết nhưng tôi đang tìm kiếm trong dấu trang của mình và hầu hết chúng được viết như stackoverflow (không có .com, v.v.)
Bruno

3
@Bruno: rất có khả năng chúng được lưu nội bộ với các tiêu đề và URL riêng biệt, như { title: "Stackoverflow", uri: "http://stackoverflow.com" } Cập nhật: thực sự, hãy xem code.google.com.vn/chrome/extensions/bookmark.html
Marcel Korpel

10
cố gắng sử dụng ví dụ của bạn Nhưng tôi đang nhận được một lỗi trên firebird mà nói invalid quantifier. Bất kỳ ý tưởng?
Sisir

125
Trả về chức năng: 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 Google Chrome (Phiên bản 30.0.1599.101) (Mac OS X: 10.8.5)
dr.dimitru

10
Xin lưu ý rằng nếu bạn sử dụng một chuỗi làm tham số cho việc RegExpbạn phải thoát gấp đôi dấu gạch chéo ngược - nếu không, bạn sẽ gặp lỗi như nhóm không hợp lệ .
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);
}

13
không thành công cho các liên kết hình ảnh tìm kiếm của 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
cái này chậm không thể sử dụng được
Hernán Eche

3
@ HernánEche Ý bạn là gì khi chậm ? start = new Date(); isURL("http://michalstefanow.com"); end = new Date(); diff = end - start; console.log(diff)Tôi đặt ấm đun nước, đi vào nhà vệ sinh, gọi cho mẹ tôi và mọi việc được thực hiện ngay lập tức ...
Mars Robertson

62
Nó trả về truecho aaa.
alex naumov

1
Điều này hoàn toàn không nên là câu trả lời chính xác. Nó thất bại trong nhiều trường hợp thử nghiệm và quan trọng hơn là nó treo trang của bạn trên một chuỗi ngắn: isURL('12345678901234567890123')thêm một số ký tự và thậm chí còn tệ hơn.
aamarks

141

Bạn có thể thử sử dụng hàm URLtạo : nếu nó không ném, chuỗi là một URL hợp lệ:

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

  return true;
}

Thuật ngữ 'URL' được định nghĩa trong RFC 3886 (dưới dạng URI); nó phải bắt đầu bằng tên lược đồ và tên lược đồ không giới hạn ở http / https.

Ví dụ đáng chú ý:

  • www.google.com URL không hợp lệ (lược đồ bị thiếu)
  • javascript:void(0) là URL hợp lệ, mặc dù không phải là HTTP
  • http://..là URL hợp lệ, với các máy chủ con người ..; nó có giải quyết hay không phụ thuộc vào DNS của bạn
  • https://google..com là URL hợp lệ, giống như trên

Nếu bạn muốn kiểm tra xem một chuỗi có phải là URL HTTP hợp lệ hay không:

function isValidHttpUrl(string) {
  let url;

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

  return url.protocol === "http:" || url.protocol === "https:";
}

13
@AshD không, không phải vậy; ví dụ: bạn không thể sử dụng làm hrefthuộc tính cho <a>. URL hợp lệ phải bắt đầu bằng một tên chương trình , ví dụ https://.
Pavlo

3
URL mới ('javascript: alert (23)')
blade091

6
@Pavlo điều này trả về đúngisValidUrl("javascript:void(0)")
Praveena

3
Tôi thích điều này vì đã dạy tôi những điều mới về js! Nó không có tiêu cực sai mà tôi có thể tìm thấy. Nó có một số điểm tích cực sai: http://..Hoặchttp:///a
aamarks

2
URL đang hoạt động bắt đầu từ Edge nên mọi thứ bên dưới nó có thể không hoạt động như bạn mong đợi. Hãy chắc chắn rằng bạn kiểm tra tính tương thích đầu tiên.
Tony T.

97

Thay vì sử dụng biểu thức chính quy, tôi khuyên bạn nên sử dụng phần tử neo.

khi bạn đặt thuộc hreftính của an anchor, nhiều thuộc tính khác được đặt.

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"

nguồn

Tuy nhiên, nếu giá trị hrefbị ràng buộc không phải là một url hợp lệ, thì giá trị của các thuộc tính phụ trợ đó sẽ là chuỗi trống.

Chỉnh sửa: như được chỉ ra trong các nhận xét: nếu sử dụng url không hợp lệ, các thuộc tính của URL hiện tại có thể được thay thế.

Vì vậy, miễn là bạn không chuyển qua URL của trang hiện tại, bạn có thể làm một cái gì đó như:

function isValidURL(str) {
   var a  = document.createElement('a');
   a.href = str;
   return (a.host && a.host != window.location.host);
}

3
Đây không phải là trường hợp (ít nhất là trong Chrome 48). Nếu url được chuyển đến a.hrefkhông hợp lệ, parser.hostsẽ trả về tên máy chủ của trang bạn hiện đang truy cập, không như mong đợi false.
Sam Beckham

2
Trời ạ! lạ nhỉ. Tôi thề tôi đã thử nghiệm điều này! Tôi nghĩ thật công bằng khi nói rằng điều này thực sự sẽ không bao giờ được sử dụng TRÊN trang hiện tại, vì vậy điều kiện có thể được thay đổi. Tôi sẽ chỉnh sửa bài viết.
Lu-ca

nó không phải là trường hợp sử dụng rất điển hình, nhưng kỹ thuật này không hoạt động trong bối cảnh cửa sổ trình duyệt Firefox (quan trọng đối với sự phát triển addon)
chrmod

@SamBeckham Đây chắc chắn là một mối quan tâm khi sử dụng phương pháp này, nhưng tôi chỉ muốn chỉ ra rằng đây không phải là một hành vi đặc biệt. Nếu bạn có một liên kết trên trang của bạn không hợp lệ, như thế <a href="invalidurl">, nó sẽ đi đến tên miền của bạn. Nó được thêm vào cuối url hiện tại. Vì vậy, Chrome đang làm điều chính xác bằng cách cung cấp cho bạn tên máy chủ hiện tại từ thành phần "trình phân tích cú pháp".
YTS

4
function isValidURL(str): tốt hơn nhiều so với sử dụng regex! Cảm ơn bạn!
Rodrigo

46

Tôi đang sử dụng chức năng dưới đây để xác thực URL có hoặc không có 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


2
Có vẻ là một giải pháp tốt đẹp! Bạn có thể thêm một số thử nghiệm cho thấy nó hoạt động trong một số trường hợp góc (xem ví dụ những bình luận này )?
Basj

@Basj thêm trường hợp kiểm tra. Vui lòng kiểm tra
Vikasdeep Singh

Không tệ, không vượt qua http: //⌘.ws hoặc 142.42.1.1 và nó cho phép http: //.www.foo.bar./ nhưng nó không bị treo như một số regex khác bao gồm các câu trả lời được xếp hạng hàng đầu.
aamarks

@aamarks Tôi đã kiểm tra câu trả lời của bạn. Câu trả lời của bạn là thất bại vì https://sdfasdp.ppppppppppptức là trả lại truenhưng falsetôi nghĩ là tôi sẽ trả lại .
Vikasdeep Singh

4
nó trở lại đúng cho sadf@gmail.com... nó nên? Tôi đoán là không nên
Zohab Ali

35

Để xác thực Url bằng cách sử dụng javascript được hiển thị bên dưới

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

3
Một số phần của regex có thể được giảm đáng kể: a) (http|https)đến (?:https?); b) :{0,1}đến :?; c) [0-9]đến\d
Dmitry Parzhitsky


23

Cải thiện câu trả lời được chấp nhận ...

  • Kiểm tra ftp / ftps như giao thức
  • Đã thoát gấp đôi cho dấu gạch chéo ngược (\\)
  • Đảm bảo rằng các tên miền có dấu chấm và phần mở rộng (.com .io .xyz)
  • Cho phép dấu hai chấm đầy đủ (:) trong đường dẫn, ví dụ: http://thingiverse.com/doad:1894343
  • Cho phép ampersand (&) trong đường dẫn, ví dụ: http://en.wikipedia.org/wiki/Procter_&_Gamble
  • Cho phép biểu tượng @ trong đường dẫn, ví dụ: 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);
    }

5
Không, nó không nên là câu trả lời được chấp nhận. Giống như một số khác, nó bị treo trên một chuỗi 33 ký tự: isURL ('123456789012345678901234567890123') và thất bại trong nhiều bài kiểm tra trường hợp cạnh: foo.com/blah_blah_(wikipedia)_(again) // trả về sai.
aamarks

2
Đó là bởi vì localhost: 8080 không phải là một URL hợp lệ.
Shane


Nên là ftps: // localhost: 8080 =)
vp_arth

Nó dường như không hoạt động: treo trên đầu vào dài (như @aanmark đã nói)
cecillac

13

Đây là một phương pháp khác.

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


Mã giáo dục! Cơ chế ở đây có lẽ giống hệt như cách new URL(string)mã của Pavlo hoạt động. Cả hai thử nghiệm đều có kết quả giống hệt nhau với tất cả các trường hợp cạnh tôi đã thử nghiệm. Tôi thích mã của anh ấy vì nó đơn giản hơn và không liên quan đến việc tạo các phần tử, nhưng mã của bạn nhanh hơn vài lần (có lẽ vì nó không tạo ra el sau lần sử dụng đầu tiên).
aamarks

1
Cảm ơn bạn! Tôi thực hiện lời khuyên của bạn. Tuy nhiên, hãy lưu ý: Các trình duyệt cũ hơn và / hoặc WebView của thiết bị di động có thể chưa triển khai phần tử <input type = url>; do đó, giá trị đầu vào sẽ được xử lý giống như một văn bản thông thường (không xác thực URL). REF: developer.mozilla.org/en-US/docs/Web/HTML/Euity/input/url
Panini luncher 7/12/18

10

(Tôi không có đại diện để nhận xét về ví dụ của RationalURL ; do đó đăng bài này dưới dạng câu trả lời.)

Trong khi sử dụng các URL tương đối giao thức không được khuyến khích ( URL giao thức tương đối ), họ được tuyển dụng đôi khi. Để xác thực một URL như vậy với một biểu thức chính quy, phần giao thức có thể là tùy chọn, ví dụ:

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

Như những người khác đã lưu ý, tuy nhiên, biểu thức chính quy dường như không phải là cách tiếp cận phù hợp nhất để xác thực các URL.


Lúc đầu tôi nghĩ nó khá tốt nhưng nó đã thất bại trong nhiều bài kiểm tra tại mathiasbynens.be/demo/url-regex , và sau đó nó bị treoisValidURL("https://d1f4470da51b49289906b3d6cbd65074@app.getsentry.com/13176")
aamarks

Vâng, như tôi đã nói, tôi chỉ bình luận về phần giao thức. Tôi đã thêm điều khoản xác thực để xử lý @. Nó không bị treo trong trình duyệt của tôi .
ko la

Xin lỗi, tôi đã trải qua một vài trong số này để đánh giá chúng và bỏ lỡ rằng bạn đang bình luận về câu trả lời đã cho. Tôi nghĩ rằng sự điều chỉnh của bạn thậm chí đã giúp tôi bắt đầu với những điều này khi lần đầu tiên tôi truy cập trang này. Không treo bây giờ.
aamarks

9

Bạn có thể sử dụng API gốc URL :

  const isUrl = string => {
      try { return Boolean(new URL(string)); }
      catch(e){ return false; }
  }

3
Trông rất giống với câu trả lời được cung cấp bởi @pavlo, chỉ có các tên biến được thay đổi;)
Munim Munna

2
bây giờ thực sự nên có một phương pháp riêng đơn giản để kiểm tra điều này - câu trả lời này có vẻ rất hứa hẹn nhưng nó trả về đúng sớm như @Basj đã đề cập ở trên.
zero_cool

8

Như đã lưu ý, regex hoàn hảo khó nắm bắt nhưng dường như vẫn là một cách tiếp cận hợp lý (các lựa chọn thay thế là các thử nghiệm phía máy chủ hoặc API URL thử nghiệm mới ). Tuy nhiên, các câu trả lời xếp hạng cao thường trả về sai cho các URL phổ biến nhưng thậm chí tệ hơn sẽ đóng băng ứng dụng / trang của bạn trong vài phút thậm chí là một chuỗi đơn giản như isURL('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'). Nó đã được chỉ ra trong một số ý kiến, nhưng hầu hết có lẽ đã không nhập một giá trị xấu để xem nó. Treo như thế làm cho mã đó không thể sử dụng trong bất kỳ ứng dụng nghiêm trọng nào. Tôi nghĩ rằng đó là do các bộ không nhạy cảm lặp đi lặp lại trong mã như thế nào ((([a-z\\d]([a-z\\d-]*[a-z\\d])*)\\.?)+[a-z]{2,}|' .... Loại bỏ 'i' và nó không bị treo nhưng tất nhiên sẽ không hoạt động như mong muốn. Nhưng ngay cả với cờ bỏ qua, các kiểm tra từ chối các giá trị unicode cao được phép.

Điều tốt nhất đã được đề cập là:

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

Điều đó xuất phát từ Github Segio / is-url . Điểm hay của kho lưu trữ mã là bạn có thể thấy thử nghiệm và mọi vấn đề cũng như chuỗi thử nghiệm chạy qua nó. Có một nhánh cho phép các chuỗi thiếu giao thức như thế google.com, mặc dù sau đó bạn có thể đưa ra quá nhiều giả định. Các kho lưu trữ đã được cập nhật và tôi không có kế hoạch cố gắng theo kịp một tấm gương ở đây. Nó đã được chia thành các thử nghiệm riêng biệt để tránh các bản đỏ RegEx có thể bị khai thác cho các cuộc tấn công DOS (Tôi không nghĩ bạn phải lo lắng về điều đó với js phía máy khách, nhưng bạn phải lo lắng về việc trang của bạn bị treo quá lâu khách truy cập rời khỏi trang web của bạn).

Có một kho lưu trữ khác mà tôi đã thấy thậm chí có thể tốt hơn cho isURL tại dperini / regex-weburl.js , nhưng nó rất phức tạp. Nó có một danh sách kiểm tra lớn hơn các URL hợp lệ và không hợp lệ. Cái đơn giản ở trên vẫn vượt qua tất cả các mặt tích cực và chỉ thất bại trong việc chặn một vài tiêu cực kỳ lạ http://a.b--c.de/như cũng như các ips đặc biệt.

Cho dù bạn chọn loại nào, hãy chạy nó thông qua chức năng này mà tôi đã điều chỉnh từ các thử nghiệm trên dperini / regex-weburl.js, trong khi sử dụng bộ kiểm tra Công cụ dành cho nhà phát triển của trình duyệt.

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:password@example.com:8080"));
console.assert(isURL("http://userid:password@example.com:8080/"));
console.assert(isURL("http://userid@example.com"));
console.assert(isURL("http://userid@example.com/"));
console.assert(isURL("http://userid@example.com:8080"));
console.assert(isURL("http://userid@example.com:8080/"));
console.assert(isURL("http://userid:password@example.com"));
console.assert(isURL("http://userid:password@example.com/"));
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:p@example.com:5702/db"));
console.assert(isURL("https://d1f4470da51b49289906b3d6cbd65074@app.getsentry.com/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"));}

Và sau đó kiểm tra chuỗi 'a's.

Xem so sánh này về regex isURL của Mathias Bynens để biết thêm thông tin trước khi bạn đăng một regex dường như tuyệt vời.


Tôi đã kiểm tra câu trả lời của bạn. Câu trả lời của bạn không thành công cho sdfasdp.ppppppppppp tức là trả lại đúng nhưng dự kiến ​​là sai
Vikasdeep Singh

1
Tôi nghĩ đó là một URL hợp lệ, có cấu trúc. Không phải là một chuyên gia về tiêu chuẩn nhưng tôi không nghĩ rằng có giới hạn về độ dài của phần .com (tôi biết .online là hợp pháp).
aamarks

1
Tôi hầu như không biết làm thế nào để viết một regex vài tháng trước. Vấn đề là nghiêm trọng. Cả hai regex tôi đã trích dẫn có thể hoàn thành isURL('a'.repeat(100))hàng triệu lần / giây (cái phức tạp hơn từ dperini thực sự nhanh hơn). Một số câu trả lời xếp hạng cao của biểu mẫu ([a-zA-Z] +) * sẽ mất hàng giờ để hoàn thành điều đó một lần. Tra cứu RegEx làm lại để biết thêm thông tin.
aamarks

6

Tôi không thể nhận xét về bài đăng gần nhất # 5717133 , nhưng dưới đây là cách tôi tìm ra cách để regex @ tom-gullen hoạt động.

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

2
Điều này làm việc cho tôi nhưng tôi cần phải gạch chéo các dấu gạch chéo ngược. 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

Kiểm tra w3resource.com/javascript-exercises/ để biết thêm các trường hợp thử nghiệm
Kewal Shah

5

Sử dụng validator.js

ES6

import isURL from 'validator/lib/isURL'

isURL(string)

Không có ES6

var validator = require('validator');

validator.isURL(string)

Bạn cũng có thể tinh chỉnh hành vi của chức năng này bằng cách chuyển optionsđối tượng tùy chọn làm đối số thứ hai củaisURL

Đây là optionsđối tượng mặc định :

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_whitelisthost_blacklistcó thể là mảng của máy chủ. Họ cũng hỗ trợ các biểu thức thường xuyên.

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

1
Đẹp! Thư viện nhỏ (dưới 40k rút gọn), thư viện phổ biến (trên 3M tải xuống hàng tuần vào npm), mang đến cho bạn sự linh hoạt trong việc chỉ định tính hợp lệ của các URL cho trường hợp sử dụng cụ thể của bạn và có một số trình xác nhận khác ngoài URL. Đây là câu trả lời tốt nhất, IMHO.
Javid Jamae

4

Một chức năng mà tôi đã và đang sử dụng để xác thực "chuỗi" URL là:

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

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

Hàm này sẽ trả về boolean cho dù chuỗi là URL.

Ví dụ:

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

4

Điều này khá khó thực hiện với regex thuần vì URL có nhiều 'bất tiện'.

  1. Ví dụ: tên miền có các hạn chế phức tạp đối với dấu gạch nối:

    a. Nó được phép có nhiều dấu gạch nối liên tiếp ở giữa.

    b. nhưng ký tự đầu tiên và ký tự cuối cùng của tên miền không thể là dấu gạch nối

    c. Ký tự thứ 3 và thứ 4 không thể là cả dấu gạch nối

  2. Tương tự số cổng chỉ có thể nằm trong phạm vi 1-65535. Điều này rất dễ kiểm tra nếu bạn trích xuất phần cổng và chuyển đổi sang intnhưng khá khó kiểm tra bằng biểu thức chính quy.

  3. Cũng không có cách dễ dàng để kiểm tra các phần mở rộng tên miền hợp lệ. Một số quốc gia có tên miền cấp hai (chẳng hạn như 'co.uk') hoặc phần mở rộng có thể là một từ dài, chẳng hạn như '.i quốc tế'. Và TLD mới được bổ sung thường xuyên. Loại điều này chỉ có thể được kiểm tra đối với một danh sách mã hóa cứng. (xem https://en.wikipedia.org/wiki/Top-level_domain )

  4. Sau đó, có các url nam châm, địa chỉ ftp, vv Tất cả đều có yêu cầu khác nhau.

Tuy nhiên, đây là một chức năng xử lý khá nhiều thứ trừ:

  • Trường hợp 1. c
  • Chấp nhận bất kỳ số cổng 1-5 chữ số
  • Chấp nhận bất kỳ ký tự mở rộng 2-13
  • Không chấp nhận ftp, nam châm, v.v ...

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] + ']');
}


1

Tôi nghĩ rằng sử dụng API URL gốc tốt hơn một mẫu biểu thức chính quy phức tạp như @pavlo đề xuất. Nó có một số nhược điểm mặc dù chúng ta có thể sửa bằng một số mã bổ sung. Cách tiếp cận này không thành công cho các url hợp lệ sau đây.

//cdn.google.com/script.js

Chúng ta có thể thêm giao thức bị thiếu trước để tránh điều đó. Nó cũng không phát hiện ra url không hợp lệ.

http://w
http://..

Vậy tại sao phải kiểm tra toàn bộ url? chúng ta chỉ có thể kiểm tra tên miền. Tôi đã mượn regex để xác minh tên miền từ đây .

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

Các hostnamethuộc tính là chuỗi rỗng cho javascript:void(0), vì vậy nó hoạt động cho điều đó quá, và bạn cũng có thể thêm địa chỉ IP xác minh quá. Tôi muốn gắn bó nhất với API gốc và hy vọng nó bắt đầu hỗ trợ mọi thứ trong tương lai gần.


Thú vị, nhưng có thể vẫn cần phải làm việc trên regex vì giờ đây nó đã đưa ra những phủ định sai mà new URLkhông có trong các thử nghiệm tôi đã thực hiện. Đây là cách gọi: http://142.42.1.1 //falsevà chặn các chuỗi unicode cao.
aamarks

1

Câu hỏi yêu cầu một phương thức xác thực cho một url, chẳng hạn như stackoverflowgiao thức hoặc bất kỳ dấu chấm nào trong tên máy chủ. Vì vậy, đây không phải là vấn đề xác thực url sintax, mà kiểm tra xem đó có phải là url hợp lệ hay không, bằng cách thực sự gọi nó.

Tôi đã thử một số phương pháp để biết liệu url đúng có tồn tại và có thể gọi được từ bên trong trình duyệt hay không, nhưng không tìm thấy cách nào để kiểm tra với javascript tiêu đề phản hồi của cuộc gọi:

  • thêm một phần tử neo là tốt để bắn click()phương thức.
  • thực hiện cuộc gọi ajax đến url đầy thách thức 'GET'là tốt, nhưng có nhiều hạn chế do CORSchính sách và đó không phải là trường hợp sử dụng ajax, vì url có thể nằm ngoài miền của máy chủ của tôi.
  • sử dụng API tìm nạp có một cách giải quyết tương tự như ajax.
  • vấn đề khác là tôi có máy chủ của mình theo httpsgiao thức và đưa ra một ngoại lệ khi gọi các url không an toàn.

Vì vậy, giải pháp tốt nhất tôi có thể nghĩ đến là CURLsử dụng một số công cụ để thực hiện bằng cách sử dụng javascript để thử một cái gì đó như thế nào curl -I <url>. Thật không may, tôi đã không tìm thấy bất kỳ và trong sự xuất hiện nó là không thể. Tôi sẽ đánh giá cao bất kỳ ý kiến ​​về điều này.

Nhưng cuối cùng, tôi có một máy chủ đang chạy PHPvà khi tôi sử dụng Ajax cho hầu hết tất cả các yêu cầu của mình, tôi đã viết một hàm ở phía máy chủ để thực hiện yêu cầu cuộn tròn ở đó và quay lại trình duyệt.

Về url từ duy nhất trong câu hỏi 'stackoverflow', nó sẽ dẫn tôi đến https://daniserver.com.ar/stackoverflow, nơi daniserver.com.ar là tên miền của riêng tôi.


OP có lẽ nên chỉ ra nhiều hơn về ý định của anh ta. Vấn đề chắc chắn thay đổi tùy theo nhu cầu của bạn và liệu điều quan trọng hơn là loại trừ dương tính giả hoặc bao gồm các phủ định sai. Khi vấn đề được nêu ra dường như không có câu trả lời cho tôi. Bạn thực sự có thể lấy foovà giả sử đó là http hoặc https hoặc .com hoặc .es hoặc bất kỳ hậu tố nào trong số vô số hậu tố không? Bạn có tiếp tục ném bồn rửa nhà bếp vào nó cho đến khi bạn có được một sự thật?
aamarks

1

Đây dường như là một trong những vấn đề khó khăn nhất trong CS;)

Đây là một giải pháp chưa hoàn chỉnh khác hoạt động đủ tốt cho tôi và tốt hơn những giải pháp khác tôi từng thấy ở đây. Tôi đang sử dụng một [type = url] đầu vào cho việc này để hỗ trợ IE11, nếu không, việc sử dụng window.URL sẽ đơn giản hơn nhiều để thực hiện xác thực thay thế:

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

Để chấp nhận các đầu vào không đầy đủ như "www.mydomain.com", nó cũng sẽ làm cho nó hợp lệ giả sử giao thức là "http" trong các trường hợp đó và trả về URL hợp lệ nếu địa chỉ hợp lệ. Nó trả về false khi không hợp lệ.

Nó cũng hỗ trợ các tên miền IPv4, nhưng không phải IPv6.


1

Trong trường hợp của tôi, yêu cầu duy nhất của tôi là đầu vào của người dùng sẽ không được hiểu là một liên kết tương đối khi được đặt trong href của thẻ và các câu trả lời ở đây là một chút OTT cho điều đó hoặc cho phép các URL không đáp ứng yêu cầu của tôi, vì vậy điều này là những gì tôi đang đi với:

^https?://.+$

Điều tương tự có thể đạt được khá dễ dàng mà không cần regex.


1

cái này làm việc với tôi

function isURL(str) {
  var regex = /(http|https):\/\/(\w+:{0,1}\w*)?(\S+)(:[0-9]+)?(\/|\/([\w#!:.?+=&%!\-\/]))?/;
  var pattern = new RegExp(regex); 
return pattern.test(str);
}

1
Câu trả lời này đã được đưa ra trên 4 năm trước bởi kavitha Reddy.
aamarks

tôi chỉ làm cho nó đơn giản và trừu tượng hơn
HeshamSalama

1

Nếu bạn có thể thay đổi loại đầu vào, tôi nghĩ giải pháp này sẽ dễ dàng hơn nhiều:

Bạn có thể sử dụng đơn giản type="url"trong đầu vào của bạn và kiểm tra nó checkValidity()trong js

Ví dụ:

của bạn.html

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

your.js

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

1

Đây không phải là cách tiếp cận hiệu quả nhất, nhưng nó có thể đọc được và dễ dàng hình thành bất cứ điều gì bạn cần. Và nó dễ dàng hơn để thêm regex / độ phức tạp từ đây. Vì vậy, đây là một cách tiếp cận rất thực tế

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

KIỂM TRA:

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

1

Mathias Bynens đã biên soạn một danh sách các biểu thức URL nổi tiếng với các URL kiểm tra. Có rất ít lý do để viết một biểu thức chính quy mới; chỉ cần chọn một cái hiện có phù hợp với bạn nhất.

Nhưng bảng so sánh cho các biểu thức chính đó cũng cho thấy rằng không thể thực hiện xác thực URL bằng một biểu thức chính quy duy nhất. Tất cả các biểu thức trong danh sách của Bynens đều tạo ra dương tính giả và âm tính giả.

Tôi khuyên bạn nên sử dụng trình phân tích cú pháp URL hiện có (ví dụ: new URL('http://www.example.com/')trong JavaScript) và sau đó áp dụng các kiểm tra bạn muốn thực hiện đối với hình thức phân tích cú pháp và chuẩn hóa của URL. các thành phần của nó. Sử dụng JavaScriptURL giao diện có lợi ích bổ sung là nó sẽ chỉ chấp nhận các URL như vậy thực sự được trình duyệt chấp nhận.

Bạn cũng nên nhớ rằng các URL không chính xác về mặt kỹ thuật vẫn có thể hoạt động. Ví dụ http://w_w_w.example.com/, http://www..example.com/, http://123.example.com/tất cả đều có một phần tên máy không hợp lệ nhưng mọi trình duyệt Tôi biết sẽ cố gắng mở chúng mà không than phiền, và khi bạn chỉ định địa chỉ IP cho những tên không hợp lệ trong/etc/hosts/ URL như vậy thậm chí sẽ làm việc nhưng chỉ trên máy tính của bạn.

Do đó, câu hỏi đặt ra là liệu URL có hợp lệ hay không, mà là URL nào hoạt động và nên được cho phép trong một ngữ cảnh cụ thể.

Nếu bạn muốn thực hiện xác thực URL, có rất nhiều chi tiết và trường hợp cạnh dễ bị bỏ qua:

  • URL có thể chứa thông tin đăng nhập như trong http://user:password@www.example.com/ .
  • Số cổng phải nằm trong phạm vi 0-65535, nhưng bạn vẫn có thể muốn loại trừ cổng ký tự đại diện 0.
  • Số cổng có thể có số 0 đứng đầu như trong http://www.example.com:000080/ .
  • Địa chỉ IPv4 hoàn toàn không bị giới hạn ở 4 số nguyên thập phân trong phạm vi 0-255. Bạn có thể sử dụng một đến bốn số nguyên và chúng có thể là số thập phân, bát phân hoặc thập lục phân. Các URL https: //010.010.000010.010/ , https: //0x8.0x8.0x0008.0x8/ , https: //8.8.2056/ , https: //8.526344/ , https: // 134744072 / đều hợp lệ và chỉ là những cách viết sáng tạo https://8.8.8.8/ .
  • Cho phép địa chỉ loopback ( http://127.0.0.1/ ), địa chỉ IP riêng ( http://192.168.1.1 ), địa chỉ liên kết cục bộ ( http://169.254.100.200 ) và như vậy có thể có tác động đến bảo mật hoặc riêng tư. Ví dụ: nếu bạn cho phép chúng là địa chỉ của avatar người dùng trong diễn đàn, bạn khiến trình duyệt của người dùng gửi yêu cầu mạng không được yêu cầu trong mạng cục bộ của họ và trên internet những điều mà những yêu cầu đó có thể gây ra những điều buồn cười và không hài hước cho xảy ra trong nhà của bạn
  • Vì những lý do tương tự, bạn có thể muốn loại bỏ các liên kết đến tên máy chủ không đủ điều kiện, nói cách khác là tên máy chủ không có dấu chấm.
  • Nhưng tên máy chủ có thể luôn có một dấu chấm (như trong http://www.stackoverflow.com.).
  • Phần tên máy chủ của liên kết có thể chứa dấu ngoặc nhọn cho các địa chỉ IPv6 như trong http: // [:: 1] .
  • Địa chỉ IPv6 cũng có phạm vi cho các mạng riêng hoặc địa chỉ liên kết cục bộ, v.v.
  • Nếu bạn chặn một số địa chỉ IPv4 nhất định, hãy nhớ rằng ví dụ https://127.0.0.1https: // [:: ffff: 127.0.0.1] trỏ đến cùng một tài nguyên (nếu thiết bị loopback của máy của bạn đã sẵn sàng IPv6 ).
  • Phần tên máy chủ của URL hiện có thể chứa Unicode, do đó phạm vi ký tự [-0-9a-zA-z]chắc chắn không còn đủ.
  • Nhiều đăng ký cho các tên miền cấp cao xác định các hạn chế cụ thể, ví dụ: trên bộ ký tự Unicode được phép. Hoặc họ chia nhỏ không gian tên của họ (như co.ukvà nhiều người khác).
  • Các tên miền cấp cao nhất không được chứa các chữ số thập phân và dấu gạch nối không được phép trừ khi có tiền tố nhãn A IDN "xn--".
  • Các tên miền cấp cao nhất của Unicode (và mã hóa kiểu mã hóa bằng "xn--") vẫn phải chỉ chứa các chữ cái nhưng ai muốn kiểm tra xem trong biểu thức chính quy?

Những hạn chế và quy tắc nào được áp dụng là một câu hỏi về yêu cầu và sở thích của dự án.

Gần đây tôi đã viết một trình xác nhận URL cho một ứng dụng web phù hợp với các URL do người dùng cung cấp trong các diễn đàn, mạng xã hội hoặc tương tự. Hãy sử dụng nó làm cơ sở cho chính bạn:

Tôi cũng đã viết một bài đăng trên blog Chi tiết Gory về Xác thực URL với thông tin sâu hơn.


1

Tôi thay đổi chức năng thành Match + thực hiện thay đổi ở đây với dấu gạch chéo và công việc của nó: (http: // và https) cả

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

0

Đây chỉ là một kiểm tra rất đơn giản để đảm bảo có một giao thức hợp lệ và phần mở rộng tên miền phải có hai hoặc nhiều ký tự.

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

};

0

Nếu bạn cũng cần hỗ trợ https://localhost:3000thì hãy sử dụng phiên bản regex [Devshed] đã sửa đổi này.

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

0

Có một vài thử nghiệm sử dụng hàm tạo URL mà không phân định xem liệu đầu vào là một chuỗi hay đối tượng 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;  
    }
}

0

Cập nhật 2020. Để mở rộng trên cả hai câu trả lời xuất sắc từ @iamnewton và @Fernando Chavez Herrera Tôi đã bắt đầu thấy @được sử dụng trong đường dẫn của URL.

Vì vậy, regex cập nhật là:

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

Nếu bạn muốn cho phép nó trong chuỗi truy vấn và hàm băm, hãy sử dụng:

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

Điều đó đang được nói, tôi không chắc chắn nếu có một quy tắc whitepaper không tuân @theo chuỗi truy vấn hoặc hàm băm.


0

Đã có rất nhiều câu trả lời, nhưng đây là một đóng góp khác: Được thực hiện trực tiếp từ URLkiểm tra tính hợp lệ của polyfill, sử dụng một inputyếu tố type="url"để tận dụng kiểm tra tính hợp lệ tích hợp của trình duyệt:

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

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

Nguồn

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.