JavaScript-호출되는 스크립트의 URL을 어떻게 얻습니까?


81

다음 http://site1.com/index.html과 같이 파일에 myscript.js를 포함 합니다.

<script src=http://site2.com/myscript.js></script>

"myscript.js"에서 URL " http://site2.com/myscript.js "에 액세스하고 싶습니다 . 다음과 같은 것을 갖고 싶습니다.

function getScriptURL() {
    // something here
    return s
}

alert(getScriptURL());

위에서 언급 한 index.html에서 호출하면 " http://site2.com/myscript.js "를 경고 합니다.




예제 URL을 기반으로 브라우저가 타사 스크립트를 차단하도록 설정된 경우 예상되는 동작을 기록 할 수 있습니다.

답변:


58

에서 http://feather.elektrum.org/book/src.html :

var scripts = document.getElementsByTagName('script');
var index = scripts.length - 1;
var myScript = scripts[index];

이제 변수 myScript에 스크립트 dom 요소가 있습니다. 을 사용하여 src URL을 가져올 수 있습니다 myScript.src.

이것은 스크립트의 초기 평가의 일부로 실행되어야합니다. Javascript 네임 스페이스를 오염시키지 않으려면 다음과 같이 할 수 있습니다.

var getScriptURL = (function() {
    var scripts = document.getElementsByTagName('script');
    var index = scripts.length - 1;
    var myScript = scripts[index];
    return function() { return myScript.src; };
})();

23
그래도 모든 브라우저에서 항상 올바른 스크립트의 URL을 반환합니까? 마지막 스크립트 태그를 반환하는 것처럼 보이지만 문서에 스크립트 태그가 두 개 이상 있으면 어떻게 될까요?
MikeC8 2010-06-04

3
좋아 ... 제 질문은 다음 스크립트 태그로 이동하기 전에 모든 브라우저가 항상 원격 스크립트의 전체 내용을 완전히로드합니까? 이 표준화는 얼마나 엄격합니까? 나는 그것이 병렬로 일어나는 것을 상상할 수 있었다 ...
MikeC8

1
스크립트 태그에 document.write가 포함 된 경우 발생할 수있는 상황 때문에 스크립트가 완전히 순서대로 실행되어야합니다. 이것은 실제로 다른 콘텐츠가로드되는 것을 차단하기 때문에 페이지 하단에 스크립트를 배치하도록 권장하는 이유입니다. 즉, HTML5는 async 및 defer 속성을 사용하여 수정합니다. whatwg.org/specs/web-apps/current-work/multipage/…
lambacck

9
다음과 같이 페이지를로드 한 후 스크립트를로드하면 작동하지 않습니다. document.getElementsByTagName("head")[0].appendChild(scriptElement);
Seanonymous

16
이 알고리즘이 안정적으로 작동하지 않는 경우를 보았습니다. 비동기로 설정된 다른 스크립트 태그는 요청되고 실행되는 스크립트간에 실행될 수 있습니다. 이 스크립트는 당신의 스크립트 뒤에 나타나는 DOM에 다른 스크립트를 추가 할 수 있습니다. 스크립트가 실행될 때 페이지의 마지막 스크립트는 더 이상 귀하의 것이 아니며 잘못된 src것이 반환됩니다.

54

스크립트 태그에 id 속성을 추가 할 수 있습니다 (헤드 태그 안에 있더라도).

<script id="myscripttag" src="http://site2.com/myscript.js"></script>

다음과 같이 src에 액세스합니다.

document.getElementById("myscripttag").src

물론 id 값은 스크립트를 포함하는 모든 문서에 대해 동일해야하지만 큰 불편은 없다고 생각합니다.


1
이 답변은 "전역"스크립트 컨텍스트 또는 "비동기"스크립트가 아닌 메서드를 호출하는 경우를 다루며 브라우저 구현에 의존하지 않으므로 "수락 됨"으로 표시되어야합니다.
Sergei Kovalenko

참고 .src상대 경로가 지정된 경우에도 절대 경로를 반환 할 수 있습니다. 당신은 사용할 수 있습니다.getAttribute('src')
Илья Зеленько에게


18

지연 로딩 및 비동기 스크립트 태그로 작동하는 스크립트 경로를 찾기 위해 클래스를 작성했습니다.

스크립트와 관련된 템플릿 파일이 있었기 때문에 하드 코딩하는 대신 클래스를 만들어 경로를 자동으로 생성했습니다. 전체 소스는 여기 github에 있습니다.

얼마 전 나는 arguments.callee를 사용하여 비슷한 작업을 시도했지만 최근 MDN 에서 Strict 모드에서는 허용되지 않는다고 읽었습니다 .

function ScriptPath() {
  var scriptPath = '';
  try {
    //Throw an error to generate a stack trace
    throw new Error();
  }
  catch(e) {
    //Split the stack trace into each line
    var stackLines = e.stack.split('\n');
    var callerIndex = 0;
    //Now walk though each line until we find a path reference
    for(var i in stackLines){
      if(!stackLines[i].match(/http[s]?:\/\//)) continue;
      //We skipped all the lines with out an http so we now have a script reference
      //This one is the class constructor, the next is the getScriptPath() call
      //The one after that is the user code requesting the path info (so offset by 2)
      callerIndex = Number(i) + 2;
      break;
    }
    //Now parse the string for each section we want to return
    pathParts = stackLines[callerIndex].match(/((http[s]?:\/\/.+\/)([^\/]+\.js)):/);
  }

  this.fullPath = function() {
    return pathParts[1];
  };

  this.path = function() {
    return pathParts[2];
  };

  this.file = function() {
    return pathParts[3];
  };

  this.fileNoExt = function() {
    var parts = this.file().split('.');
    parts.length = parts.length != 1 ? parts.length - 1 : 1;
    return parts.join('.');
  };
}

1
파티에 조금 늦었지만이 코드 조각을 시도한 결과 for 루프 "callerIndex = Number (i) + 2;"의 현재 인덱스에 2를 추가하는 부분이 발견되었습니다. 파손이 불필요 해 보이고 작동하지 않는 것 같습니다. 단순히 "+ 2"를 제거하면 작동합니다. 내가 잘못 해석하고 있거나 + 2가 필요한 다른 시나리오가 있습니까?
Scott Smith

2
이런 식으로 "Error"를 던질 필요는 없습니다 ( ".stack"을 얻으려면) 다른 사람들과 같은 객체 일뿐입니다 : console.log (new Error (). stack);
Abdullah

1
이 아이디어에 감사하고 던지기 방지 아이디어에 대해 @ AbdullahAydın에게 감사드립니다. 그렇다면 다음 한 줄짜리가 트릭을 할 것 같지 않습니까? var scriptUrl = new Error (). stack.match (/ @ (https? : \ / \ /.+) : \ d + : \ d + /) [1]
Pierre-Antoine

1
또한 @ Pierre-Antoine은 Error.prototype.stack 속성이 표준이 아니라는 점을 명심하십시오. : / 조심해서 사용해야합니다. developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…
Abdullah

3
@ AbdullahAydın : 새 오류의 스택 속성은 오류가 발생할 때까지 IE 및 Edge 브라우저에 채워 지지 않습니다 .
Bob Arlof

15

jQuery를 사용할 기회가 있다면 코드는 다음과 같습니다.

$('script[src$="/myscript.js"]').attr('src');

지연, 비동기 및 지연 로딩 스크립트와 함께 작동합니까?
Stephan

DOM을 통해 src "/myscript.js"가있는 스크립트 태그를 찾고 있습니다. 다른 속성은 중요하지 않습니다
Rebs

버전을 추가하는 다른 위치에서 워드 프레스와 함께 사용하려면 $ ( 'script [src * = "/ myscript.js"]'). attr ( 'src'); 이렇게하면 스크립트 끝에서? ver = 2.3.3을 무시합니다. *는 끝에 무엇이 있는지에 관계없이 계속 작동합니다.
Mav2287

15

매우 잘 작동하는 간단하고 직접적인 솔루션 :

IE가 아니라면 document.currentScript
For IE를 사용할 수 있습니다 document.querySelector('script[src*="myscript.js"]')
.

function getScriptURL(){
 var script =  document.currentScript || document.querySelector('script[src*="myscript.js"]')
 return script.src
}

2

다음 코드를 사용하면 주어진 이름으로 스크립트 요소를 찾을 수 있습니다.

var scripts = document.getElementsByTagName( 'script' );
        var len = scripts.length
        for(var i =0; i < len; i++) {
            if(scripts[i].src.search("<your JS file name") > 0 && scripts[i].src.lastIndexOf("/") >= 0) {
                absoluteAddr = scripts[i].src.substring(0, scripts[i].src.lastIndexOf("/") + 1);
                break;
            }
        }

-6

location.href 또는 location.host를 사용한 다음 스크립트 이름을 추가 할 수 없습니까?


1
스크립트가 site1.com/index.html 페이지 내에서 실행되기 때문에 작동하지 않습니다 . 따라서 스크립트가 site2.com에서로드 된 경우에도 스크립트 내에서 위치에 액세스하면 " site1.com/index.html " 을 반환합니다 ...
MikeC8
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.