Saya mencoba memuat beberapa skrip ke dalam halaman menggunakan innerHTML
di a <div>
. Tampaknya skrip dimuat ke DOM, tetapi tidak pernah dieksekusi (setidaknya di Firefox dan Chrome). Apakah ada cara agar skrip dijalankan saat memasukkannya innerHTML
?
Kode sampel:
<!DOCTYPE html>
<html>
<body onload="document.getElementById('loader').innerHTML = '<script>alert(\'hi\')<\/script>'">
Shouldn't an alert saying 'hi' appear?
<div id="loader"></div>
</body>
</html>
sumber
<script>
taginnerHTML
mungkin pendek, tetapi tidak berhasil. Itu semua hanya teks biasa sampai dijalankaneval()
. Dan sayangnya,eval()
tidak mem-parsing tag HTML, jadi Anda berakhir dengan serangkaian masalah.Berikut ini solusi yang sangat menarik untuk masalah Anda: http://24ways.org/2005/have-your-dom-and-script-it-too
Jadi gunakan ini sebagai ganti tag skrip:
<img src="empty.gif" onload="alert('test');this.parentNode.removeChild(this);" />
sumber
onload
atribut. Juga ini membutuhkan file tambahan untuk ada dan dimuat. solusi momo kurang kompromi.<img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7">
(ini tidak akan melakukan permintaan jaringan) Sebenarnya ... Anda TIDAK membutuhkan gambar, referensi gambar yang tidak ada dan alih-alihonload
menggunakanonerror
(tapi ini akan melakukan permintaan jaringan)Berikut adalah metode yang secara rekursif mengganti semua skrip dengan skrip yang dapat dieksekusi:
Contoh panggilan:
sumber
Anda dapat membuat skrip lalu menyuntikkan konten.
Ini bekerja di semua browser :)
sumber
document.documentElement
sebagai gantinya.<script>
var g = document.createElement('script');
var s = document.getElementsByTagName('script')[0]; //reference this script
g.text = "alert(\"hi\");"
s.parentNode.insertBefore(g, s);
</script>
<script>
elemen. Misalnya<img onerror="..." src="#">
dan<body onload="...">
. Jika Anda ingin teknis, ini tidak akan berfungsi dalam dokumen non-HTML / SVG karena penempatan nama yang tidak jelas.Saya menggunakan kode ini, itu berfungsi dengan baik
sumber
Saya punya masalah dengan innerHTML ini, saya harus menambahkan skrip Hotjar ke tag "head" aplikasi Reactjs saya dan harus dijalankan segera setelah menambahkan.
Salah satu solusi bagus untuk impor Node dinamis ke tag "head" adalah modul React-helment .
Juga, ada solusi yang berguna untuk masalah yang diusulkan:
Tidak ada tag skrip di innerHTML!
Ternyata HTML5 tidak memungkinkan tag skrip ditambahkan secara dinamis menggunakan properti innerHTML. Jadi yang berikut tidak akan dieksekusi dan tidak akan ada peringatan yang mengatakan Hello World!
Ini didokumentasikan dalam spesifikasi HTML5:
Namun berhati-hatilah, ini tidak berarti innerHTML aman dari skrip lintas situs. Dimungkinkan untuk menjalankan JavaScript melalui innerHTML tanpa menggunakan tag seperti yang diilustrasikan pada halaman innerHTML MDN .
Solusi: Menambahkan skrip secara dinamis
Untuk menambahkan tag skrip secara dinamis, Anda perlu membuat elemen skrip baru dan menambahkannya ke elemen target.
Anda dapat melakukan ini untuk skrip eksternal:
Dan skrip sebaris:
sumber
Bagi siapa pun yang masih mencoba melakukan ini, tidak, Anda tidak dapat menyuntikkan skrip menggunakan
innerHTML
, tetapi dimungkinkan untuk memuat string ke tag skrip menggunakan aBlob
danURL.createObjectURL
.Saya telah membuat contoh yang memungkinkan Anda menjalankan string sebagai skrip dan mendapatkan 'ekspor' skrip dikembalikan melalui janji:
Saya telah menyederhanakan ini dari implementasi saya yang sebenarnya, jadi tidak ada janji bahwa tidak ada bug di dalamnya. Tapi prinsipnya berhasil.
Jika Anda tidak peduli untuk mendapatkan nilai kembali setelah skrip berjalan, itu bahkan lebih mudah; hanya meninggalkan keluar
Promise
danonload
bit. Anda bahkan tidak perlu membungkus skrip atau membuatwindow.__load_script_exports_
properti global .sumber
Berikut ini adalah fungsi rekursif untuk mengatur innerHTML elemen yang saya gunakan di server iklan kami:
Anda dapat melihat demo di sini .
sumber
Anda bisa melakukannya seperti ini:
sumber
Di sini solusi yang tidak digunakan
eval
, dan bekerja dengan skrip , skrip yang ditautkan , serta dengan modul .Fungsi menerima 3 parameter:
sumber
eval('console.log(this)')
dan Anda akan melihat yang paling jelaseval('let b=100')
.. lalu coba aksesb
dari luar eval .... semoga berhasil, Anda akan membutuhkannyaKrasimir Tsonev memiliki solusi hebat yang mengatasi semua masalah. Metodenya tidak perlu menggunakan eval, jadi tidak ada masalah kinerja atau keamanan. Ini memungkinkan Anda untuk mengatur string innerHTML berisi html dengan js dan menerjemahkannya segera ke elemen DOM sementara juga mengeksekusi bagian js yang ada di sepanjang kode. pendek, sederhana, dan berfungsi persis seperti yang Anda inginkan.
Nikmati solusinya:
http://krasimirtsonev.com/blog/article/Convert-HTML-string-to-DOM-element
Catatan penting:
sumber
Gunakan
$(parent).html(code)
sebagai gantiparent.innerHTML = code
.Berikut ini juga memperbaiki skrip yang menggunakan
document.write
dan skrip dimuat melaluisrc
atribut. Sayangnya bahkan ini tidak berfungsi dengan skrip Google AdSense.Sumber
sumber
Coba gunakan template dan document.importNode. Berikut ini sebuah contoh:
sumber
Anda juga dapat membungkus Anda
<script>
seperti ini dan itu akan dieksekusi:Harap dicatat: Ruang lingkup di dalam
srcdoc
mengacu pada iframe, jadi Anda harus menggunakantop
seperti pada contoh di atas untuk mengakses dokumen induk.sumber
Ya Anda bisa, tetapi Anda harus melakukannya di luar DOM dan pesanannya harus benar.
... akan mengingatkan 'foo'. Ini tidak akan berfungsi:
Dan bahkan ini tidak akan berhasil, karena simpulnya dimasukkan terlebih dahulu:
sumber
Solusi saya untuk masalah ini adalah mengatur Pengamat Mutasi untuk mendeteksi
<script></script>
node dan kemudian menggantinya dengan<script></script>
node baru dengan src yang sama. Sebagai contoh:sumber
Penyebutan Gabriel Garcia tentang MutationObservers ada di jalur yang benar, tetapi tidak berhasil bagi saya. Saya tidak yakin apakah itu karena kekhasan browser atau karena kesalahan pada saya, tetapi versi yang akhirnya bekerja untuk saya adalah sebagai berikut:
Tentu saja, Anda harus mengganti
element_to_watch
dengan nama elemen yang sedang dimodifikasi.node.parentElement.added
digunakan untuk menyimpan tag skrip yang ditambahkandocument.head
. Dalam fungsi yang digunakan untuk memuat halaman eksternal, Anda dapat menggunakan sesuatu seperti berikut ini untuk menghapus tag skrip yang tidak lagi relevan:Dan contoh dari awal fungsi pemuatan:
sumber
MutationObserver
setiap kali elemen ditambahkan ke dokumen, kan? Btw, saya bertanya-tanya mengapa Anda mengatakan kode saya tidak berfungsi.Bagi saya cara terbaik adalah memasukkan konten HTML baru melalui innerHtml dan kemudian gunakan
SetTimeout tidak diperlukan tetapi berfungsi lebih baik. Ini berhasil untuk saya.
sumber
Jalankan tag (Java Script) dari innerHTML
Ganti elemen skrip Anda dengan div yang memiliki atribut class class = "javascript" dan tutup dengan
</div>
Jangan ubah konten yang ingin Anda jalankan (sebelumnya sudah ada di tag skrip dan sekarang sudah ada di tag div)
Tambahkan gaya di halaman Anda ...
<style type="text/css"> .javascript { display: none; } </style>
Sekarang jalankan eval menggunakan jquery (Jquery js harus sudah termasuk)
Anda dapat menjelajahi lebih lanjut di sini , di blog saya.
sumber