Ketika saya merender halaman menggunakan renderer template Django, saya bisa memberikan variabel kamus yang berisi berbagai nilai untuk memanipulasi mereka di halaman menggunakan {{ myVar }}
.
Apakah ada cara untuk mengakses variabel yang sama dalam Javascript (mungkin menggunakan DOM, saya tidak tahu bagaimana Django membuat variabel dapat diakses)? Saya ingin dapat mencari rincian menggunakan pencarian AJAX berdasarkan nilai-nilai yang terkandung dalam variabel yang diteruskan.
escapejs
ada filter:escapejs('<>') -> u'\\u003C\\u003E'
HATI-HATI Periksa tiket # 17419 untuk diskusi tentang menambahkan tag serupa ke inti Django dan kemungkinan kerentanan XSS yang diperkenalkan dengan menggunakan tag templat ini dengan data yang dibuat pengguna. Komentar dari amacneil membahas sebagian besar kekhawatiran yang muncul dalam tiket.
Saya pikir cara paling fleksibel dan praktis untuk melakukan ini adalah dengan mendefinisikan filter template untuk variabel yang ingin Anda gunakan dalam kode JS. Ini memungkinkan Anda untuk memastikan, bahwa data Anda lolos dengan benar dan Anda dapat menggunakannya dengan struktur data yang kompleks, seperti
dict
danlist
. Itu sebabnya saya menulis jawaban ini meskipun ada jawaban yang diterima dengan banyak upvotes.Berikut ini contoh filter templat:
Filter template ini mengonversi variabel menjadi string JSON. Anda dapat menggunakannya seperti ini:
sumber
safe
hanya menandai nilai sebagai aman, tanpa konversi dan melarikan diri yang tepat.function myWidget(config) { /* implementation */ }
dalam file JS dan daripada Anda menggunakannya pada beberapa halaman menggunakanmyWidget({{ pythonConfig | js }})
. Tetapi Anda tidak dapat menggunakannya dalam file JS (seperti yang Anda perhatikan), sehingga memiliki keterbatasan.Solusi yang berfungsi untuk saya adalah menggunakan bidang input tersembunyi di template
Kemudian dapatkan nilai dalam javascript dengan cara ini,
sumber
Pada Django 2.1, baru dibangun di tag template telah diperkenalkan secara khusus untuk kasus penggunaan ini:
json_script
.https://docs.djangoproject.com/en/3.0/ref/templates/builtins/#json-script
Tag baru akan membuat serialisasi nilai template dengan aman dan melindungi terhadap XSS.
Kutipan dokumen Django:
sumber
Inilah yang saya lakukan dengan sangat mudah: Saya memodifikasi file base.html untuk template saya dan meletakkannya di bagian bawah:
kemudian ketika saya ingin menggunakan variabel dalam file javascript, saya membuat kamus DJdata dan saya menambahkannya ke konteks oleh json:
context['DJdata'] = json.dumps(DJdata)
Semoga ini bisa membantu!
sumber
Untuk kamus, Anda sebaiknya melakukan enkode ke JSON terlebih dahulu. Anda bisa menggunakan simplejson.dumps () atau jika Anda ingin mengonversi dari model data di App Engine, Anda bisa menggunakan encode () dari pustaka GQLEncoder.
sumber
Saya menghadapi masalah yang sama dan jawaban yang disarankan oleh S.Lott bekerja untuk saya.
Namun saya ingin menunjukkan batasan implementasi utama di sini. Jika Anda berencana untuk meletakkan kode javascript Anda di file yang berbeda dan memasukkan file itu ke dalam template Anda. Ini tidak akan berhasil.
Ini bekerja hanya ketika Anda template utama dan kode javascript di file yang sama. Mungkin tim Django dapat mengatasi keterbatasan ini.
sumber
Saya telah berjuang dengan ini juga. Di permukaan, tampaknya solusi di atas harus bekerja. Namun, arsitektur Django mensyaratkan bahwa setiap file html memiliki variabel yang dirender sendiri (yaitu,
{{contact}}
diberikan kecontact.html
, sementara{{posts}}
pergi ke misalnyaindex.html
dan seterusnya). Di sisi lain,<script>
tag muncul setelah{%endblock%}
inbase.html
dari manacontact.html
danindex.html
mewarisi. Ini pada dasarnya berarti bahwa semua solusi termasukpasti gagal, karena variabel dan skrip tidak dapat hidup berdampingan dalam file yang sama.
Solusi sederhana yang akhirnya saya buat, dan bekerja untuk saya, adalah dengan hanya membungkus variabel dengan tag dengan id dan kemudian merujuknya dalam file js, seperti:
lalu:
dan hanya termasuk
<script src="static/js/somecode.js"></script>
dalambase.html
seperti biasa. Tentu saja ini hanya tentang mendapatkan konten. Mengenai keamanan, cukup ikuti jawaban lain.sumber
.textContent
sebagai gantinya.innerHTML
, karena jika tidak entitas yang mendapatkan HTML-encoded akan menjadi bagian dari variabel JS juga. Tetapi bahkan saat itu mungkin tidak direproduksi 1: 1 (Saya tidak yakin).Untuk objek JavaScript yang disimpan dalam bidang Django sebagai teks, yang perlu lagi menjadi objek JavaScript yang disisipkan secara dinamis ke dalam skrip on-page, Anda perlu menggunakan keduanya
escapejs
danJSON.parse()
:Django
escapejs
menangani kutipan dengan benar, danJSON.parse()
mengubah string kembali menjadi objek JS.sumber
Perhatikan, bahwa jika Anda ingin meneruskan variabel ke skrip .js eksternal maka Anda harus mengawali tag skrip Anda dengan tag skrip lain yang mendeklarasikan variabel global.
data
didefinisikan dalam tampilan seperti biasa diget_context_data
sumber
Saya menggunakan cara ini di Django 2.1 dan bekerja untuk saya dan cara ini aman (referensi) :
Sisi Django:
Sisi html:
sumber
Anda bisa merakit seluruh skrip tempat variabel array Anda dinyatakan dalam sebuah string, seperti berikut,
yang akan menghasilkan string sebagai berikut
setelah memiliki string ini, Anda harus mengirimnya ke templat
dalam template Anda menerimanya dan menafsirkannya dengan cara sastra sebagai kode htm, tepat sebelum kode javascript di mana Anda membutuhkannya, misalnya
dan di bawah itu adalah sisa kode Anda, perlu diingat bahwa variabel yang digunakan dalam contoh adalah data2
dengan cara itu Anda akan menyimpan tipe data, yang dalam hal ini adalah pengaturan
sumber
aaa
hanya akan berisi angka, jika tidak XSS (injeksi skrip) dimungkinkan.Ada dua hal yang berhasil bagi saya di dalam Javascript:
dan lainnya: Di views.py
dan di html:
sumber