programing

URL 문자열이 절대적인지 또는 상대적인지 테스트하는 방법은 무엇입니까?

css3 2023. 9. 27. 18:05

URL 문자열이 절대적인지 또는 상대적인지 테스트하는 방법은 무엇입니까?

자바스크립트나 jQuery에서 상대적이거나 절대적인 경로일 경우 URL을 테스트하려면 어떻게 해야 합니까?전달된 URL이 로컬 경로인지 외부 경로인지에 따라 처리하고 싶습니다.

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

빠른

경우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('git+ssh://example.con/item'); // true - absolute URL with '+' in scheme
r.test('/myfolder/test.txt'); // false - relative URL
r.test('test'); // false - also relative URL

RegExp 설명

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

^ --
(?:이 아닌 - 캡처
[a-z+]+ -에서 z는 "+"를 1
:)-열자)
)?이 아닌 -비 포획된입니다입니다이 0 경우 0는 1
// 슬래시)-열개)
'i' 구분 안하는 -

var pat = /^https?:\/\//i;
if (pat.test(urlString))
{
    //do stuff
}

프로토콜 상대 URL의 경우 다음 regex를 사용합니다.

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

필요에 따라서 이것을 판단하는 더 확실한 방법은 내장된 URL 인터페이스를 이용하여 몇 개의 URL 객체를 구성하고 출처를 비교하는 것이라고 생각합니다.

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

이를 통해 브라우저는 엣지 케이스의 부작용을 걱정할 필요 없이 이 모든 것을 파싱하고 파악할 수 있습니다.

원답

매우 빠르고 유연한 검사는 다음과 같습니다.

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 또는 기타 종속성 없음.
  • 조건 케이스를 민감하게 만드는 하드코딩된 프로토콜 이름이 없습니다.
  • 문자열 조작 없음(예: 소문자 또는 유사).
  • "상대적 또는 절대적" 검사만 수행하고 다른 정상성 검사는 수행하지 않으며 웹 URL 또는 내부 프로토콜에 사용할 수 있습니다.

업데이트 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 (URLs inside URL param)

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
}

그리고 짧은 형태와 ES 6에서도 마찬가지입니다.

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

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

테스트 사례는 다음과 같습니다.

// Test
console.log( isUrlAbsolute('http://stackoverflow.com') ) // -> true
console.log( isUrlAbsolute('//stackoverflow.com') ) // -> true
console.log( isUrlAbsolute('stackoverflow.com') ) // -> false
console.log( isUrlAbsolute('Ftp://example.net') ) // -> true
console.log( isUrlAbsolute('/redirect?target=http://example.org') ) // -> false

업데이트 3 (관련 URL 명확화)

잘못된 출력에 대한 몇 가지 의견을 보았습니다.

  • 이 false 를합니다에 합니다.localhost
  • 에 대한 실패http:example.com

그러나 이러한 URL은 실제로 상대적인 URL입니다.테스트하기 쉽습니다.

  1. webroot 와 localhost webroot에 를 몇 개합니다.a/b/c/
  2. .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.comhtml 파일에 입력할 수 있습니다.http://example.com 대신 http://localhost/a/b/c/example.com 에서 종료합니다.

regex 사용:

if (/^(?:[a-z]+:)?\/\//i.test(url))

더욱 보편적인 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

섹션 4.2에 따라 프로토콜 관련 URL이 기술적으로 유효하지만 Paul Irish는 반대로 전환하여 이를 안티 패턴으로 간주합니다.http://www.paulirish.com/2010/the-protocol-relative-url/ 참조

4.2. 상대 참조 https://www.rfc-editor.org/rfc/rfc3986#section-4.2

protocol-relative url을 사용하지 않고 regex를 원하는 경우:

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

다른 유형의 유효한 uri edge 사례의 전체 목록을 보려면 여기에서 목록을 확인하십시오. https://en.wikipedia.org/wiki/URI_scheme

시도 및 캐치 블록을 사용하여 이 문제를 해결할 수 있습니다.정규 표현식을 사용하는 대신 모든 단계에서 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
}

요즘은 많은 서비스가 프로토콜 relative URL(예: //cdn.example.com/libary.js), )을 사용할 때 더 안전합니다.

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

if (isAbsolute.test(urlString)) {
  // go crazy here
}

regexp 등 낮은 수준의 것은 사용하지 마세요.이런 일들은 다른 많은 사람들에 의해 해결되었습니다.특히 엣지 케이스.

URI.js를 보십시오. http://medialize.github.io/URI.js/docs.html#is 이 작동할 것입니다.

var uri = new URI("http://example.org/");
uri.is("absolute") === true;

브라우저 환경을 위한 매우 강력한 솔루션은 다음과 같습니다.

브라우저가 모든 것을 처리하게 합니다.복잡하거나 오류가 발생하기 쉬운 일부 정규화 작업이 필요 없습니다.

const isAbsoluteUrl = (url) => {
  const link = document.createElement('a');
  link.href = url;
  return link.origin + link.pathname + link.search + link.hash === url;
};
var external = RegExp('^(https?:)?//');
if(external.test(el)){
    // do something
}

편집:

다음 정규식을 사용하면 링크가 같은 도메인으로 이동하는지 또는 외부 도메인으로 이동하는지도 확인할 수 있습니다.

var external = RegExp('^((f|ht)tps?:)?//(?!' + location.host + ')');
if(external.test(el)){
    // do something
}
var adress = 'http://roflmao.com';
if (adress.substr(0,7) == 'http://' || adress.substr(0,8) == 'https://') {
    //
}

된 두 하지 못했습니다.redirect_url합니다./\/example.com아니면/\\/example.com 우리의 리디렉션 URL이 상대적인지 확인하기 위해 생각해낸 것은 다음과 같습니다.

var isRelative = !redirectUrl.match(/(\:|\/\\*\/)/);  // Don't allow "//" (with optional "\"'s) or ":"

슬래시나 해시로 시작해서는 안 되며 물음표나 해시 앞에 없으면 이중 슬래시를 포함해서는 안 됩니다.저는 단일 regexp로 테스트하지 않을 것입니다. "이중 슬래시 없음"을 맞추는 것은 매우 복잡할 것입니다.

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

더 쉽고, 더 선명하고, 훨씬 더 빠를 겁니다.

하이퍼링크에서 클릭 이벤트가 발생하면 다음 함수가 호출됩니다. 즉, 태그에 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';
        }
    }); 
});

표준 URL 생성기를 사용하면 다음과 같은 이점이 있습니다.

const url = new URL(urlToTest);
const isAbsolute = url.protocol && url.hostname

그리고 보너스로 당신의 값이 유효한 URL인지 확인할 것입니다.

var isExternalURL = url.toLowerCase().indexOf('http://') === 0 || url.toLowerCase().indexOf('https://') === 0 ;

언급URL : https://stackoverflow.com/questions/10687099/how-to-test-if-a-url-string-is-absolute-or-relative