Parametreler bir Komut Dosyası etiketine nasıl aktarılır?


96

Ben öğretici okuma DIY widget'lar - Başka bir sitede sitenize nasıl gömülür? Dr Nic tarafından XSS Widgets için.

Komut dosyası etiketine parametreleri aktarmanın bir yolunu arıyorum. Örneğin, aşağıdakilerin çalışmasını sağlamak için:

<script src="http://path/to/widget.js?param_a=1&amp;param_b=3"></script>

Bunu yapmanın bir yolu var mı?


İki ilginç bağlantı:


Yanıtlar:


124

Çok eski bir soruyu yanıtladığım için özür dilerim, ancak yukarıdaki çözümlerle güreşerek bir saat geçirdikten sonra daha basit şeyler seçtim.

<script src=".." one="1" two="2"></script>

Yukarıdaki komut dosyasının içinde:

document.currentScript.getAttribute('one'); //1
document.currentScript.getAttribute('two'); //2

Jquery VEYA url ayrıştırmadan çok daha kolay.

@Yared Rodriguez'in IE cevabından doucment.currentScript için polyfil'e ihtiyacınız olabilir:

document.currentScript = document.currentScript || (function() {
  var scripts = document.getElementsByTagName('script');
  return scripts[scripts.length - 1];
})();

6
CurrentScript'in IE'de çalışmadığını unutmayın. Ayrıntılar
Dehli

Cevaba IE için bir polyfill ekledim. Polyfill çalışmıyor mu?
Richard Fox

2
polyfill artık çalışmamaktadır, document.currentScript salt okunurdur ve zaten mevcutsa atanamaz. eğer (! document.currentScript) {*** polyfill işlevi ***} daha iyi
çalışırsa

3
Özür dilerim David, cevaplarımı her zaman genel yapıyorum, böylece başkaları sorunları ekleyen ilk uygulama ayrıntıları olmadan çözümü kullanabilir. Yukarıdaki src="..."örneğimde şunu görebilirsiniz: Bu, HERHANGİ bir src'yi belirtmek içindir, önemli değil :)
Richard Fox

1
@RichardFox cevabınız için teşekkürler, ancak "Orijinal soruyu cevaplamıyor: / widget.js yolunu kullanmıyor" muhtemelen tüm hafta okuduğum en komik şey! Yaptığın kadar kibarca cevapladığına inanamıyorum.
Skintest

65

Özelliği html5 5 veri Özniteliklerinde kullanmak daha iyidir

<script src="http://path.to/widget.js" data-width="200" data-height="200">
</script>

Http://path.to/widget.js komut dosyası dosyasında , paremetreleri şu şekilde alabilirsiniz:

<script>
function getSyncScriptParams() {
         var scripts = document.getElementsByTagName('script');
         var lastScript = scripts[scripts.length-1];
         var scriptName = lastScript;
         return {
             width : scriptName.getAttribute('data-width'),
             height : scriptName.getAttribute('data-height')
         };
 }
</script>

Ya id = "myAwesomeWigretNo1" her zaman böyle değilse myAwesomeWigretNo2, ya da myAwesomeWigretNo681??? Bunu gerçek bir değişkeni kabul edecek şekilde nasıl düzeltebilirim?
Pathros

9
Ne 's değerinde için, örneğin yerine senaryoyu referans için başka yollar vardır document.currentScriptbir koyarak (sadece kendi dosyasında komut için çalışır) ve idüzerinde <script>etiketi ve o bunu bulmakta.
Thunderforge

Peki ya kimlik, ekibinizde bu kimliği kullandığınıza dair hiçbir fikri olmayan başka bir programcı tarafından değiştirildiyse?
OBender

1
Komut dosyalarını eşzamansız olarak yüklerseniz, bir kimlik kullanmak tavsiye edeceğim tek güvenilir seçenektir. Teşekkürler @Thunderforge ... Ayrıca, herhangi bir programcı, neler olup bittiğine dair bir ipucu olan biri tarafından gözden geçirilen uygun bir sprint planı olmadan bir kodu yeniden düzenlemekten kaçınmalıdır;)
Luca Borrione

Elbette Geliştiricilerden güçlü bir Etik talep edebilirsiniz, ancak uzun vadede işe yaramayacaktır ... İnsanlar bir şeyleri unutur ... İyi Bir Yazılım Tasarımında Her Blok Parçası izole edilir, harika-pixels.tumblr.com/post/101930002170 /… En.wikipedia.org/wiki/SOLID_(object-oriented_design) Bu yüzden bunun iyi ve kötü bir çözüm olduğunu iddia etmiyorum, ID'leri korumaktan korumamaktan daha karmaşık :-) Planlamıyor musunuz betiği Async yükle ID kullanarak yüklemek için bir neden görmüyorum
OBender

17

Anladım. Bir çeşit hack, ama oldukça iyi çalışıyor:

var params = document.body.getElementsByTagName('script');
query = params[0].classList;
var param_a = query[0];
var param_b = query[1];
var param_c = query[2];

Komut dosyası etiketindeki parametreleri sınıflar olarak geçiriyorum:

<script src="http://path.to/widget.js" class="2 5 4"></script>

Bu makale çok yardımcı oldu.


1
Makale harika!
Bartek Skwira

14
Sınıflar, parametreleri iletmemek için öğeye stil uygulamak için kullanılmalıdır.
kspacja

5
@kspacja Evet ve HTML sadece stil içermeyen içerik içermelidir, tek fark kayan nokta ve sütun düzenleri için DIV etiketlerimizi hassas bir şekilde sıralamak zorundayız çünkü CSS işi gerçekten yapamaz ve biz bir şekilde bu konuda sorun yaşamıyoruz. Kes şunu diyorum. Ancak, çatışmayı önlemek istiyorsanız veya üzerinde uykunuzu kaybedecek bir türseniz, "veri" özniteliklerini kullanabilirsiniz.
Jason C

14

Başka bir yol da meta etiketleri kullanmaktır. JavaScript'inize aktarılması gereken veriler şu şekilde atanabilir:

<meta name="yourdata" content="whatever" />
<meta name="moredata" content="more of this" />

Veriler daha sonra meta etiketlerinden şu şekilde çekilebilir (en iyi şekilde DOMContentLoaded olay işleyicisinde yapılır):

var data1 = document.getElementsByName('yourdata')[0].content;
var data2 = document.getElementsByName('moredata')[0].content;

Kesinlikle jQuery veya beğenilerle uğraşmaz, kesmek ve geçici çözüm gerekmez ve meta etiketleri destekleyen herhangi bir HTML sürümüyle çalışır ...


Bu yöntemin hepsi için en kolay yöntem olduğunu düşündüm. Bir cazibe gibi çalışıyor ve bana tam olarak ihtiyacım olanı veriyor. Harika soru ve Harika çözüm!
arios

10

JQuery, parametreleri HTML'den javascript'e aktarmanın bir yolunu sunar:

Bunu myhtml.htmldosyaya koyun :

<!-- Import javascript -->
<script src="//code.jquery.com/jquery-1.11.2.min.js"></script>
<!-- Invoke a different javascript file called subscript.js -->
<script id="myscript" src="subscript.js" video_filename="foobar.mp4">/script>

Aynı dizinde bir subscript.jsdosya oluşturun ve bunu oraya koyun:

//Use jquery to look up the tag with the id of 'myscript' above.  Get 
//the attribute called video_filename, stuff it into variable filename.
var filename = $('#myscript').attr("video_filename");

//print filename out to screen.
document.write(filename);

Sonucu Analiz Et:

Myhtml.html sayfasının yüklenmesi, ekrana yazdır 'foobar.mp4' içeriyor. Video_filename adlı değişken html'den javascript'e geçirildi. Javascript bunu ekrana yazdırdı ve üstteki html'ye gömülü olarak göründü.

jsfiddle, yukarıdakilerin işe yaradığının kanıtı:

http://jsfiddle.net/xqr77dLt/


7

Jquery kullanıyorsanız , veri yöntemlerini düşünmek isteyebilirsiniz .

Cevabınızda denediğiniz şeye benzer bir şey kullandım ama şunun gibi:

<script src="http://path.to/widget.js" param_a = "2" param_b = "5" param_c = "4">
</script>

GET parametrelerini doğrudan yakalamanıza izin veren bir işlev de oluşturabilirsiniz (bu, sıklıkla kullandığım şeydir):

function $_GET(q,s) {
    s = s || window.location.search;
    var re = new RegExp('&'+q+'=([^&]*)','i');
    return (s=s.replace(/^\?/,'&').match(re)) ? s=s[1] : s='';
}

// Grab the GET param
var param_a = $_GET('param_a');

4

JQuery sayesinde HTML5 uyumlu basit bir çözüm, verileri depolamak için div gibi fazladan bir HTML etiketi oluşturmaktır.

HTML :

<div id='dataDiv' data-arg1='content1' data-arg2='content2'>
  <button id='clickButton'>Click me</button>
</div>

JavaScript :

$(document).ready(function() {
    var fetchData = $("#dataDiv").data('arg1') + 
                    $("#dataDiv").data('arg2') ;

    $('#clickButton').click(function() {
      console.log(fetchData);
    })
});

Yukarıdaki kodla canlı demo: http://codepen.io/anon/pen/KzzNmQ?editors=1011#0

Canlı demoda, birleştirilecek ve günlüğe yazdırılacak HTML5 data- * özniteliklerinden veriler görülebilir.

Kaynak: https://api.jquery.com/data/


1
Diğer çözümlerden bazılarını gözden geçirdik, ancak bu, en iyi sonuç veren ve aynı zamanda uygulanması oldukça basit olandı. Teşekkürler!
Erik Kalkoken

Komut dosyasına kimliğe göre atıfta bulunmanıza izin verdiği ve geçerli HTML5 olduğu için bu kabul edilen çözüm olmalıdır.
Tim S

4

bu çok eski bir konu, biliyorum ama biri bir çözüm aradıktan sonra buraya gelirse bu da yardımcı olabilir.

Temel olarak, kodumun çalıştığı öğeyi almak için document.currentScript'i kullandım ve aradığım değişkenin adını kullanarak filtre uyguladım. CurrentScript'i "get" adlı bir yöntemle genişleterek yaptım, böylece bu komut dosyasının içindeki değeri şunu kullanarak getirebileceğiz:

document.currentScript.get('get_variable_name');

Bu şekilde, özel nitelikler eklemeden değişkenleri almak için standart URI kullanabiliriz.

Bu son koddur

document.currentScript.get = function(variable) {
    if(variable=(new RegExp('[?&]'+encodeURIComponent(variable)+'=([^&]*)')).exec(this.src))
    return decodeURIComponent(variable[1]);
};

IE'yi unutuyordum :) Bu kadar kolay olamazdı ... Document.currentScript'in bir HTML5 özelliği olduğundan bahsetmemiştim. IE'nin farklı sürümleri için dahil edilmemiştir (IE11'e kadar test ettim ve henüz orada değildi). IE uyumluluğu için bu bölümü koda ekledim:

document.currentScript = document.currentScript || (function() {
  var scripts = document.getElementsByTagName('script');
  return scripts[scripts.length - 1];
})();

Burada yaptığımız şey, çözümde src özelliğinden parametreleri çıkarmak için gerekli olan geçerli komut dosyası nesnesini döndüren IE için bazı alternatif kodlar tanımlamaktır. Bazı sınırlamalar olduğundan, bu IE için mükemmel bir çözüm değildir; Komut dosyası eşzamansız olarak yüklenirse. Daha yeni tarayıcılar ".currentScript" özelliğini içermelidir.

Umut ediyorum bu yardım eder.


4

Aşağıdaki gibi, parametrelerin bir listesini içeren bir öznitelik oluşturun:

<script src="http://path/to/widget.js" data-params="1, 3"></script>

Ardından, JavaScript'inizde parametreleri bir dizi olarak alın:

var script = document.currentScript || 
/*Polyfill*/ Array.prototype.slice.call(document.getElementsByTagName('script')).pop();

var params = (script.getAttribute('data-params') || '').split(/, */);

params[0]; // -> 1
params[1]; // -> 3

Bu yaklaşımın olumsuz yönleri nelerdir?
Tronathan

@Tronathan, bu yaklaşımın gerçek bir dezavantajı yoktur ve daha iyi tarayıcı desteği için dahil edilen bir çoklu dolgu vardır. Burada gördüğüm tek dezavantaj, parametrelere virgül ekleyememek, ki bu genellikle bir sorun değildir ve sınırlayıcıyı kullanmayı planlamadığınız bir karakterle değiştirerek bunu telafi edebilirsiniz.
Mistik

2

İhtiyacınız olan değerleri, gizli bir girdi gibi diğer komut dosyasının onları alabileceği bir yere koyun ve ardından yeni komut dosyanızı başlattığınızda bu değerleri konteynerlerinden alın. Hatta tüm parametrelerinizi bir JSON dizesi olarak tek bir gizli alana koyabilirsiniz.


Cevabın için teşekkür ederim. Parametreler aslında kullanıcılar (bu komut dosyası etiketini kodlarına yerleştiren) tarafından girilir. Sonra ne?
Tomer Lichtash

Her iki istemci / sunucu komut dosyası üzerinde kontrolünüz yoksa, düşünebildiğim tek şey, kullanıcıların girişini alıp, girişleri gömülü olan belirli bir .js dosyası oluşturmak için kullanmaktır ve bu, kontrolün sizde olduğunu varsayar. girdilerinin toplanması ve işlenmesi.
bwest

Orijinal soruya cevap vermiyor: Gizli alanı tutacak bir form olmadığında argümanlar nereye yerleştirilecek?
David Spector

2

Mümkün olduğunca eski tarayıcıları destekleyen çözümler istedim. Aksi takdirde, ya currentScript ya da veri nitelikleri yönteminin en şık olacağını söyleyebilirim .

Bu yöntemlerden henüz burada gündeme getirilmeyen tek budur. Özellikle, herhangi bir nedenle büyük miktarda veriniz varsa, o zaman en iyi seçenek şu olabilir:

yerel depolama

/* On the original page, you add an inline JS Script: */
<script>
   localStorage.setItem('data-1', 'I got a lot of data.');
   localStorage.setItem('data-2', 'More of my data.');
   localStorage.setItem('data-3', 'Even more data.');
</script>

/* External target JS Script, where your data is needed: */
var data1 = localStorage.getItem('data-1');
var data2 = localStorage.getItem('data-2');
var data3 = localStorage.getItem('data-3');

localStorage, tam modern bir tarayıcı desteğine ve diğerlerinin yanı sıra IE 8, Firefox 3,5 ve Safari 4'e [on bir yıl önce] kadar eski tarayıcılar için şaşırtıcı derecede iyi bir desteğe sahiptir.

Çok fazla veriniz yoksa, ancak yine de kapsamlı tarayıcı desteği istiyorsanız, belki de en iyi seçenek şudur:

Meta etiketleri [Robidu tarafından]

/* HTML: */
<meta name="yourData" content="Your data is here" />

/* JS: */
var data1 = document.getElementsByName('yourData')[0].content;

Bunun kusuru, meta etiketleri yerleştirmek için doğru yerin [HTML 4'e kadar] head etiketinde olmasıdır ve bu verileri orada istemeyebilirsiniz. Bundan kaçınmak veya meta etiketleri gövdeye yerleştirmek için şunları kullanabilirsiniz:

Gizli paragraf

/* HTML: */
<p hidden id="yourData">Your data is here</p>

/* JS: */
var yourData = document.getElementById('yourData').innerHTML;

Daha fazla tarayıcı desteği için gizli özellik yerine bir CSS sınıfı kullanabilirsiniz:

/* CSS: */
.hidden {
   display: none;
}

/* HTML: */
<p class="hidden" id="yourData">Your data is here</p>

2

JQuery 3.4 için Çözüm Budur

<script src="./js/util.js" data-m="myParam"></script>
$(document).ready(function () {
    var m = $('script[data-m][data-m!=null]').attr('data-m');
})
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.