JavaScript 파일에 매개 변수 전달


163

종종 웹 페이지에 특정 변수를 정의 해야하는 JavaScript 파일을 사용하려고합니다.

따라서 코드는 다음과 같습니다.

<script type="text/javascript" src="file.js"></script>
<script type="text/javascript">
   var obj1 = "somevalue";
</script>

그러나 내가하고 싶은 것은 :

<script type="text/javascript" 
     src="file.js?obj1=somevalue&obj2=someothervalue"></script>

다른 방법을 시도했지만 가장 좋은 방법은 다음과 같이 쿼리 문자열을 구문 분석하는 것입니다.

var scriptSrc = document.getElementById("myscript").src.toLowerCase();

그런 다음 내 값을 검색하십시오.

내 문자열을 구문 분석하는 함수를 작성하지 않고 이것을 수행하는 다른 방법이 있는지 궁금합니다.

모두 다른 방법을 알고 있습니까?


9
이것은 중복 질문 ( stackoverflow.com/questions/1017424/… )이며 제 생각에는 잘못된 설계입니다. 첫 번째 변수 솔루션을 사용하거나 (좋아) 스크립트에서 변수를 사용하여 호출하는 함수를 정의하는 것이 훨씬 간단합니다 (더 나은).
Matthew Flaschen 2019

새로운 ECMAScript 6 기능을 활용하는 업데이트 된 솔루션을 찾고 있습니다. 만약 있다면
Chef_Code

내부 스크립트를 사용하면 사이트가 HTTPS이고 CSP가 완전히 활성화 된 경우 CSP 보고서가 트리거됩니다. CSP 문서에 제공된 이유는 내부 요소를 허용하여 주입을 더 쉽게 할 수 있기 때문입니다.
David Spector

답변:


207

가능하면 전역 변수를 사용하지 않는 것이 좋습니다. 네임 스페이스와 OOP를 사용하여 인수를 객체로 전달하십시오.

이 코드는 file.js에 속해 있습니다.

var MYLIBRARY = MYLIBRARY || (function(){
    var _args = {}; // private

    return {
        init : function(Args) {
            _args = Args;
            // some other initialising
        },
        helloWorld : function() {
            alert('Hello World! -' + _args[0]);
        }
    };
}());

그리고 html 파일에서 :

<script type="text/javascript" src="file.js"></script>
<script type="text/javascript">
   MYLIBRARY.init(["somevalue", 1, "controlId"]);
   MYLIBRARY.helloWorld();
</script>

4
@Naeem-MYLIBRARY.init ([ "somevalue", 1, "controlId"])의 100 %가로드 된 file.js입니다. 처형? 어쩌면 그것을 넣을 준비가 된 문서가 필요할까요?
Darius. V

2
1) MYLIBRARY가 존재하면이를 사용하거나 새 오브젝트를 정의하십시오. 의도는 전역 네임 스페이스를 만드는 것입니다. 일반적으로 하위 네임 스페이스를 사용 하므로이 줄은 최상위 네임 스페이스를 다시 정의하지 않아도됩니다. 2) 예, 싱글 톤을 만들었습니다.
Naeem Sarfraz

1
이 아이디어의 예를 만들었습니다 : http://plnkr.co/edit/iE0Vr7sszfqrrDIsR8Wi?p=preview
robe007

1
이 표현은 무엇을 의미합니까? var MYLIBRARY = MYLIBRARY || (function(){}());? MYLIBRARY부울 값으로 설정 해야하는 이유는 무엇 입니까?
Alex


79

임의의 속성으로 매개 변수를 전달할 수 있습니다. 이것은 모든 최신 브라우저에서 작동합니다.

<script type="text/javascript" data-my_var_1="some_val_1" data-my_var_2="some_val_2" src="/js/somefile.js"></script>

somefile.js 내부에서 다음과 같이 전달 된 변수 값을 얻을 수 있습니다.

........

var this_js_script = $('script[src*=somefile]'); // or better regexp to get the file name..

var my_var_1 = this_js_script.attr('data-my_var_1');   
if (typeof my_var_1 === "undefined" ) {
   var my_var_1 = 'some_default_value';
}
alert(my_var_1); // to view the variable value

var my_var_2 = this_js_script.attr('data-my_var_2');   
if (typeof my_var_2 === "undefined" ) {
   var my_var_2 = 'some_default_value';
}
alert(my_var_2); // to view the variable value

...기타...


1
아주 좋은 해결책은 비동기 속성에서도 작동합니다.
ViRuSTriNiTy

2
오래되었지만 인터넷 검색의 경우 CSP (콘텐츠 보안 정책)를 해결해야하는 경우 유용합니다. 언어 리소스 및 API 키 등에서 결정된 문자열을 JS 파일로 전달하는 많은 스크립트를 사용합니다.
monkeySeeMonkeyDo

2
참고도 사용할 수있는 document.currentScript참조 caniuse.com/#feat=document-currentscript 호환성을 위해 (또는 polyfill 사용)
이브 M.

$(..)구문을 포함하는 것을 잊지 마세요, JQuery와있다.
Timo

48

내가 본 또 다른 아이디어 id<script>요소에 an 을 할당 하고 인수를 data-*속성으로 전달 하는 것이 었습니다 . 결과 <script>태그는 다음과 같습니다.

<script id="helper" data-name="helper" src="helper.js"></script>

그런 다음 스크립트는 id를 사용하여 프로그래밍 방식으로 자체를 찾고 인수를 구문 분석 할 수 있습니다. 이전 <script>태그가 주어지면 다음 과 같이 이름을 검색 할 수 있습니다.

var name = document.getElementById("helper").getAttribute("data-name");

우리는 name=helper


4
id 속성에 의존하지 않으려면 페이지의 helper.js모든 script태그를 통해 스크립트를 반복하여로 태그를 scr="helper.js"찾은 다음 extract를 추출 할 수도 data-name있습니다.
jvannistelrooy

1
@jvannistelrooy 시도하지 않았지만 jquery와 영리한 선택기를 통해 스크립트에 액세스 할 수 있어야한다고 생각합니다. var this_js_script = $('script[src*=somefile]');( 위에서 복사 됨 )
LosManos

19

이 URL을 확인하십시오. 요구 사항에 완벽하게 작동합니다.

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

저자에게 감사합니다. 빠른 참조를 위해 아래의 주요 논리를 붙여 넣었습니다.

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

var queryString = myScript.src.replace(/^[^\?]+\??/,'');

var params = parseQuery( queryString );

function parseQuery ( query ) {
  var Params = new Object ();
  if ( ! query ) return Params; // return empty object
  var Pairs = query.split(/[;&]/);
  for ( var i = 0; i < Pairs.length; i++ ) {
    var KeyVal = Pairs[i].split('=');
    if ( ! KeyVal || KeyVal.length != 2 ) continue;
    var key = unescape( KeyVal[0] );
    var val = unescape( KeyVal[1] );
    val = val.replace(/\+/g, ' ');
    Params[key] = val;
  }
  return Params;
}

1
이 솔루션을 좋아했지만 조각 식별자를 사용하도록 캐시를 버스트하지 않도록 약간 수정했습니다. var frag = myScript.src.replace (/ ^ [^ \ #] + \ #? /, '') ;
Mark Nottingham

아, 그리고 당신이 JSON을 urlencode하는 한 JSON을 거기에 넣는 것이 효과적이라는 것을 알았습니다.
Mark Nottingham

@ user378221-이것이 항상 올바른 파일을 얻습니까? 나는 이것이이 파일이 마지막이라고 가정한다는 것을 의미합니다. 이를 실행하기 전에 더 많은 스크립트 태그가로드되면 어떻게됩니까? 가능한지 모르겠지만 문서가 다른 태그를로드하기 위해 코드 실행을 기다리지 않는다고 가정합니까?
Darius. V

사용하는 것이 더 좋습니다. 이스케이프 처리 대신 decodeURI () 또는 decodeURIComponent ()를 사용하십시오. 해당 기능은 더 이상 사용되지 않습니다.
Steve Childs

@ Darius.V 비동기가 아닌 스크립트에서 작동합니다. 폴백으로 옵션 1과 옵션 1을 함께 사용하는 것이 좋습니다 .
Luke

14

전역 변수 :-D를 사용합니다.

이처럼 :

<script type="text/javascript">
   var obj1 = "somevalue";
   var obj2 = "someothervalue";
</script>
<script type="text/javascript" src="file.js"></script">

에 'file.js'가 액세스 할 수있는 자바 스크립트 코드 obj1obj2문제없이.

편집 'file.js'가 확인 obj1하고 obj2심지어 선언 된 경우 다음 함수를 사용할 수 있는지 추가하고 싶습니다 .

function IsDefined($Name) {
    return (window[$Name] != undefined);
}

도움이 되었기를 바랍니다.


IE에서 참조되지 않은 오류가 발생합니다. 이 함수의 기본 본문은입니다 return typeof window[$Name] !== 'undefined';. 해당 함수에 변수 이름이 포함 된 문자열을 전달한다는 점에 유의하십시오. 를 통해 변수가 호출 코드에 존재하는지 쉽게 확인할 수 있습니다 (이것은 함수로 구현할 수 없습니다) if (typeof var !== 'undefined').
Anthony DiSanti

2
아, 절대로 IE를 사용하지 마십시오. 죄송합니다.
NawaMan

예, 그러나 JavaScript에 대한 내 경험에 따르면 모듈 네임 스페이스에 대해서만 전역 변수를 사용하고 여기에 표시된 것처럼 필요한만큼 (init 코드, 일부 속성과 같은) 노출 합니다 . 복잡한 프로젝트에서 이름 충돌을 일으키는 것은 너무 쉽습니다. 시간을 보내고 프로젝트의 다른 곳에서 이미 변수를 사용한 것을 알 수 있습니다.
Matt

을 생략 할 수 있습니다 var.
티모

12

여기에 매우 서두른 개념 증명이 있습니다.

개선이 가능한 곳이 2 곳 이상 있다고 확신하며, 이것이 오래 지속되지는 않을 것이라고 확신합니다. 더 유용하거나 유용하게 만드는 피드백은 환영합니다.

핵심은 스크립트 요소의 ID를 설정하는 것입니다. 유일한 발견은 스크립트가 ID를 찾아 쿼리 문자열을 가져 오기 때문에 스크립트를 한 번만 호출 할 수 있다는 것입니다. 대신 스크립트가 모든 쿼리 요소를 반복하여 해당 요소가 가리키는 지 확인한 다음 해당 스크립트 요소의 마지막 인스턴스를 사용하는 경우이 문제를 해결할 수 있습니다. 어쨌든, 코드와 함께 :

호출되는 스크립트 :

window.onload = function() {
//Notice that both possible parameters are pre-defined.
//Which is probably not required if using proper object notation
//in query string, or if variable-variables are possible in js.
var header;
var text;

//script gets the src attribute based on ID of page's script element:
var requestURL = document.getElementById("myScript").getAttribute("src");

//next use substring() to get querystring part of src
var queryString = requestURL.substring(requestURL.indexOf("?") + 1, requestURL.length);

//Next split the querystring into array
var params = queryString.split("&");

//Next loop through params
for(var i = 0; i < params.length; i++){
 var name  = params[i].substring(0,params[i].indexOf("="));
 var value = params[i].substring(params[i].indexOf("=") + 1, params[i].length);

    //Test if value is a number. If not, wrap value with quotes:
    if(isNaN(parseInt(value))) {
  params[i] = params[i].replace(value, "'" + value + "'");
 }

    // Finally, use eval to set values of pre-defined variables:
 eval(params[i]);
}

//Output to test that it worked:
document.getElementById("docTitle").innerHTML = header;
document.getElementById("docText").innerHTML = text;
};

다음 페이지를 통해 스크립트가 호출되었습니다.

<script id="myScript" type="text/javascript" 
        src="test.js?header=Test Page&text=This Works"></script>

<h1 id="docTitle"></h1>
<p id="docText"></p>

eval은 실제로 값을 전역 변수로 설정합니다 ... 매우 멋집니다.
rodmjay

1
평가는 악의 도망
배리 채프먼

@ barrychapman-oh man, 2010. 거기에 10 개의 다른 붉은 깃발이없는 것이 놀랍습니다.
Anthony

9

매우 간단 할 수 있습니다

예를 들어

<script src="js/myscript.js?id=123"></script>
<script>
    var queryString = $("script[src*='js/myscript.js']").attr('src').split('?')[1];
</script>

그런 다음 아래와 같이 쿼리 문자열을 json으로 변환 할 수 있습니다

var json = $.parseJSON('{"' 
            + queryString.replace(/&/g, '","').replace(/=/g, '":"') 
            + '"}');

다음처럼 사용할 수 있습니다

console.log(json.id);

6

jQuery와 같은 Javascript 프레임 워크를 사용하는 경우 쉽게 수행 할 수 있습니다. 이렇게

var x = $('script:first').attr('src'); //Fetch the source in the first script tag
var params = x.split('?')[1]; //Get the params

이제 변수 매개 변수로 분할하여 이러한 매개 변수를 사용할 수 있습니다.

프레임 워크 없이도 동일한 프로세스를 수행 할 수 있지만 더 많은 코드가 필요합니다.


2
parseQuery라는 jQuery 플러그인도 있습니다. plugins.jquery.com/project/parseQuery
Jimmy Cuadra

@JimmyCuadra-불행히도 제공 한 링크가 손상되었습니다. 그러나 jQuery 자체에서 비슷한 접근법을 발견했습니다. jQuery.param ()
Matt

1

글쎄, 모든 스크립팅 언어로 자바 스크립트 파일을 작성하여 모든 요청시 파일에 변수를 주입 할 수 있습니다. 웹 서버에 js 파일을 정적으로 제거하지 않도록 지시해야합니다 (mod_rewrite를 사용하면 충분합니다).

이 js 파일은 지속적으로 변경되므로 캐싱이 손실됩니다.

안녕.


1
이것이 다운 보트 된 이유를 이해할 수 없습니다. 서버 측 로직을 사용하는 완벽하게 유효한 솔루션입니다. 내가 아는 한 OP는 완전히 자바 스크립트 솔루션 일 필요는 없습니다.
Anoyz

@aefxx-맞습니다. <script>블록 내부에서 MyModule.Initialize( '<%: Model.SomeProperty%>', '<%: Model.SomeOtherProperty%>', ...);서버에서 렌더링되는 것과 같은 것을 사용할 수 있습니다 . 주의 : 값을 이스케이프 처리하고 이스케이프 처리하지 않은 값 <%:<%=전송합니다. MyModule네임 스페이스 (즉, .js 파일 내부의 변수로 자체 호출되어 함수를 노출시키는 변수 Initialize)입니다. 도움이 되었기 때문에 답변을 찬성했습니다.
Matt

참고 : 방법을 자세히 설명되어 노출 된 속성을 포함하는 모듈을 만드는 개념, 여기에 이 페이지를.
Matt

1

좋은 질문과 창의적인 답변이지만 제 제안은 메서드를 매개 변수화하여 트릭없이 모든 문제를 해결하는 것입니다.

기능이있는 경우 :

function A()
{
    var val = external_value_from_query_string_or_global_param;
}

이것을 다음으로 변경할 수 있습니다.

function B(function_param)
{
    var val = function_param;
}

나는 이것이 가장 자연스러운 접근법이라고 생각합니다. '파일 매개 변수'에 대한 추가 문서를 작성할 필요가 없으며 동일한 것을받습니다. 다른 개발자가 js 파일을 사용할 수 있도록하는 경우 특히 유용합니다.


0

아니요, JS 파일 URL의 쿼리 문자열 부분에 변수를 추가하면 실제로이 작업을 수행 할 수 없습니다. 귀찮게하는 문자열을 구문 분석하기 위해 코드 부분을 작성하는 경우 다른 방법은 변수를 json 인코딩하여 태그의 rel 속성과 같은 변수에 넣는 것입니다. HTML 유효성 검사 측면에서 이것이 얼마나 유효한지 잘 모르겠습니다. 그런 다음 스크립트의 rel 속성을 찾은 다음 json_decode 만하면됩니다.

예 :

<script type='text/javascript' src='file.js' rel='{"myvar":"somevalue","anothervar":"anothervalue"}'></script>

2
가짜 쿼리 문자열로 할 수 있습니다. 좋은 생각이 아닙니다. 그러나 이것도 아닙니다. rel 속성은 임의의 데이터를 스크립트 태그에 넣지 않고 링크 관계 유형을 지정하기위한 것입니다.
Matthew Flaschen 2019

1
^^ 동의했습니다. 나는 그대로 그대로두고 가장 좋은 방법 인 <script> var obj1 = "somevalue"</ script> 접근 방식을 사용하는 데 아무런 문제가 없으며 올바른 방법이라고 생각합니다.
Dal Hundal

0

유효한 HTML은 아니지만 (생각하지는 않습니다) 웹 페이지에서 스크립트 태그에 대한 사용자 정의 속성을 만들면 작동 하는 것 같습니다 .

<script id="myScript" myCustomAttribute="some value" ....>

그런 다음 자바 스크립트에서 사용자 정의 속성에 액세스하십시오.

var myVar = document.getElementById( "myScript" ).getAttribute( "myCustomAttribute" );

이것이 스크립트 소스 문자열을 구문 분석하는 것보다 낫거나 나쁜지 확실하지 않습니다.


0

CSP 검사를 통과하는 방법 (안전하지 않은 인라인을 금지 함)이 필요한 경우 nonce 메소드를 사용하여 스크립트와 CSP 지시문에 고유 한 값을 추가하거나 값을 html에 쓰고 다시 읽어야합니다.

express.js를위한 Nonce 메소드 :

const uuidv4 = require('uuid/v4')

app.use(function (req, res, next) {
  res.locals.nonce = uuidv4()
  next()
})

app.use(csp({
  directives: {
    scriptSrc: [
      "'self'",
      (req, res) => `'nonce-${res.locals.nonce}'`  // 'nonce-614d9122-d5b0-4760-aecf-3a5d17cf0ac9'
    ]
  }
}))

app.use(function (req, res) {
  res.end(`<script nonce="${res.locals.nonce}">alert(1 + 1);</script>`)
})

또는 HTML 메소드에 값을 쓰십시오. 이 경우 Jquery를 사용하십시오.

<div id="account" data-email="{{user.email}}"></div>
...


$(document).ready(() => {
    globalThis.EMAIL = $('#account').data('email');
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.