Hướng dẫn django pass variable to javascript file - django chuyển biến vào tệp javascript

Câu hỏi này phải rõ ràng nhưng tôi không thể tìm ra nó.

Trong một mẫu, tôi liên kết đến một tệp JS trong thư mục phương tiện của mình. Từ tệp đó, tôi muốn truy cập một biến ngữ cảnh như


6.

Nhưng cú pháp có khác nhau không ?? Cảm ơn bạn!!

Hướng dẫn django pass variable to javascript file - django chuyển biến vào tệp javascript

Shaedrich

5.2612 Huy hiệu vàng27 Huy hiệu bạc39 Huy hiệu Đồng2 gold badges27 silver badges39 bronze badges

Hỏi ngày 30 tháng 12 năm 2011 lúc 20:45Dec 30, 2011 at 20:45

1

Ngoài câu trả lời của Andrzej Bobak, bạn cũng có thể tạo một biến toàn cầu trong JavaScript từ mẫu của mình. Ví dụ: mẫu của bạn có thể tạo mã như thế này:


Kịch bản của bạn sau đó có thể tham khảo


7.

Đã trả lời ngày 31 tháng 12 năm 2011 lúc 2:23Dec 31, 2011 at 2:23

Brian Nealbrian NealBrian Neal

31.3K7 Huy hiệu vàng54 Huy hiệu bạc59 Huy hiệu đồng7 gold badges54 silver badges59 bronze badges

5

Tôi không nghĩ rằng nó có thể theo cách này. Nếu bạn muốn truy cập một số dữ liệu được cung cấp bởi chế độ xem, bạn phải chuyển nó cho chức năng JS.

Thí dụ

Tệp JS:

my_cool_js_function(some_param){
    // do some cool stuff
}

lượt xem

// some html code

my_cool_js_function({{param}})

hi vọng điêu nay co ich :)

Đã trả lời ngày 30 tháng 12 năm 2011 lúc 20:57Dec 30, 2011 at 20:57

Andrzej Bobakandrzej BobakAndrzej Bobak

2.1163 huy hiệu vàng30 huy hiệu bạc36 Huy hiệu đồng3 gold badges30 silver badges36 bronze badges

1

Tôi cũng sẽ thêm vì tôi đã gặp lỗi một vài lần rằng nếu biến Python là một đối tượng, nó sẽ ném lỗi cú pháp trừ khi bạn đặt nó vào báo giá, nói cách khác, trong mẫu của bạn,


Hơn nữa, trước khi đặt đối tượng đó vào ngữ cảnh, tốt nhất là trước tiên nên tuần tự hóa nó thành JSON, hoặc cuối cùng bạn sẽ phải thực hiện phân tích cú pháp chuỗi. Tôi cũng thấy rằng các đối tượng ngày cần phải được chuyển đổi thành chuỗi trước bước này.

import jsonpickle

context['python_object'] = jsonpickle.encode(python_object)

Và cuối cùng, trong JS, sau đó bạn có thể lặp lại thông qua đối tượng và sử dụng các giá trị như bạn có thể có trong Python bằng cách làm:

var my_var_parsed = jQuery.parseJSON(my_var);

Đã trả lời ngày 7 tháng 4 năm 2016 lúc 22:44Apr 7, 2016 at 22:44

Mastachimpmastachimpmastachimp

4183 Huy hiệu bạc14 Huy hiệu Đồng3 silver badges14 bronze badges

Hiện tại có một cách an toàn hơn để chuyển ngữ cảnh sang tệp JavaScript bằng cách sử dụng thẻ mẫu tích hợp


8 với một đối số sẽ là ID được đặt cho phần tử được tạo.

Trường hợp sử dụng sẽ là:

{{ mydata|json_script:"mydata" }}

Sau đó liên kết tệp JavaScript của bạn:


Thẻ tập lệnh sẽ phải đến sau thẻ mẫu mà tôi đoán là

Sau đó có thể được truy cập trong tệp JavaScript của bạn như:

const mydata = JSON.parse(document.getElementById('mydata').textContent);

Nguồn

Django 3.1 Docs json_script

Một nguồn khác với lời giải thích thích hợp

Đã trả lời ngày 12 tháng 1 năm 2021 lúc 14:31Jan 12, 2021 at 14:31

Hướng dẫn django pass variable to javascript file - django chuyển biến vào tệp javascript

name-andyname-andyname-andy

Huy hiệu vàng 40311 gold badge5 silver badges12 bronze badges

2022-10-06 Bạn muốn chuyển dữ liệu của mình từ chế độ xem Django của bạn sang JavaScript, trong mẫu của bạn. Và, bạn muốn làm điều đó một cách an toàn, không có nguy cơ vô tình cho phép tiêm mã độc. Tuyệt vời, đây là bài viết cho bạn!
Hướng dẫn django pass variable to javascript file - django chuyển biến vào tệp javascript

You want to pass your data from your Django view to JavaScript, in your template. And, you want to do it securely, with no risk of accidentally allowing malicious code injection. Great, this is the post for you!

Chúng tôi sẽ xem xét các vấn đề với JavaScript tạo khuôn mẫu, sau đó là hai kỹ thuật:

  • Thuộc tính dữ liệu cho các giá trị đơn giản
  • 
    
    8 cho các giá trị phức tạp

Và cuối cùng, một số lựa chọn khác mà tôi không đề xuất.

Đi nào!

CẬP NHẬT (2022-10-21) Kênh YouTube Bugbytes có video dựa trên bài đăng này, thể hiện hai kỹ thuật được phê duyệt. The BugBytes Youtube channel has a video based on this post, demonstrating the two approved techniques.

Templating javascript don don làm việc

Nhiều nhà phát triển thử trực tiếp các thẻ nội tuyến

import jsonpickle

context['python_object'] = jsonpickle.encode(python_object)
0:

{# DON’T DO THIS #}
<script>
    const username = "{{ username }}";
script>

Tôi khuyên bạn không bao giờ làm điều này!never do this!

Điều này nói chung không hoạt động, vì Django thực hiện HTML-ESCAPING trên giá trị. Ví dụ: nếu

import jsonpickle

context['python_object'] = jsonpickle.encode(python_object)
1 là
import jsonpickle

context['python_object'] = jsonpickle.encode(python_object)
2, đầu ra sẽ là:

my_cool_js_function(some_param){
    // do some cool stuff
}
0

Điều này có nghĩa là hiển thị tên người dùng không chính xác.

Ngoài ra, nó cực kỳ nguy hiểm nếu bạn mẫu các biến không chuỗi hoặc sử dụng các mẫu JavaScript (các chuỗi F F sử dụng BackTicks). Ví dụ: lấy mẫu này:

my_cool_js_function(some_param){
    // do some cool stuff
}
1

Một giá trị độc hại có thể sử dụng backtick để kết thúc theo nghĩa đen, sau đó thêm JavaScript tùy ý. Ví dụ: nếu

import jsonpickle

context['python_object'] = jsonpickle.encode(python_object)
1 là:

my_cool_js_function(some_param){
    // do some cool stuff
}
2

Sau đó, HTML sẽ là:

my_cool_js_function(some_param){
    // do some cool stuff
}
3

Mã này xác định

import jsonpickle

context['python_object'] = jsonpickle.encode(python_object)
4, sau đó chèn
import jsonpickle

context['python_object'] = jsonpickle.encode(python_object)
0 vào DOM có nguồn gốc từ
import jsonpickle

context['python_object'] = jsonpickle.encode(python_object)
6. Kịch bản đó có thể đánh cắp tất cả dữ liệu người dùng. Panik !!!Panik!!!

Hệ thống mẫu Django chỉ thoát HTML. Nó không được thiết kế để thoát các giá trị bên trong JavaScript, có cú pháp rộng hơn.

Trong khi khuôn mẫu JavaScript hoạt động trong các tình huống hạn chế, vì nó không an toàn, tôi khuyên bạn nên không bao giờ làm điều đó. Nó rất khó để duy trì các biến betwee tách biệt luôn chứa các ký tự an toàn và những biến số mà don. Ngoài ra, chỉ có một số thẻ và bộ lọc nhất định là an toàn. Trong thời gian, cuối cùng bạn sẽ giới thiệu các lỗ hổng bảo mật.never do it. It’s too hard to maintain a separation betwee variables that always contain safe characters, and those which don’t. Also, only certain tags and filters are safe. In time, you’ll eventually introduce security holes.

Thay vào đó, sử dụng một trong hai kỹ thuật sau đây.

Sử dụng các thuộc tính dữ liệu cho các giá trị đơn giản

Để chuyển các giá trị đơn giản cho JavaScript của bạn, nó rất thuận tiện khi sử dụng các thuộc tính dữ liệu:

my_cool_js_function(some_param){
    // do some cool stuff
}
4

import jsonpickle

context['python_object'] = jsonpickle.encode(python_object)
7 cung cấp quyền truy cập nhanh vào phần tử
import jsonpickle

context['python_object'] = jsonpickle.encode(python_object)
0 hiện tại. Thuộc tính
import jsonpickle

context['python_object'] = jsonpickle.encode(python_object)
9 của nó chứa các thuộc tính được truyền dưới dạng chuỗi.

Các tập tin tập lệnh riêng biệt

Bạn cũng có thể sử dụng

import jsonpickle

context['python_object'] = jsonpickle.encode(python_object)
7 cho các tệp tập lệnh riêng biệt:

my_cool_js_function(some_param){
    // do some cool stuff
}
5

… Đọc giống nhau:

my_cool_js_function(some_param){
    // do some cool stuff
}
6

Simples!

Tôi khuyên bạn nên sử dụng các tệp tập lệnh riêng biệt càng nhiều càng tốt. Họ tốt hơn cho hiệu suất vì trình duyệt có thể lưu trữ mã. Ngoài ra, bạn có thể thiết lập Chính sách bảo mật nội dung (CSP) để không cho phép các thẻ tập lệnh nội tuyến, điều này ngăn chặn XSS Attacks, xem bài đăng tiêu đề bảo mật của tôi.)

Chuyển đổi trường hợp

Tài sản

import jsonpickle

context['python_object'] = jsonpickle.encode(python_object)
9 chuyển đổi trường hợp kebab thành Camelcase. Ví dụ: nếu bạn có
var my_var_parsed = jQuery.parseJSON(my_var);
2:

my_cool_js_function(some_param){
    // do some cool stuff
}
7

Bạn có thể đọc nó trong JavaScript là

var my_var_parsed = jQuery.parseJSON(my_var);
3:

my_cool_js_function(some_param){
    // do some cool stuff
}
8

HTML kebab trở thành lạc đà javascript.

Các loại không chuỗi

import jsonpickle

context['python_object'] = jsonpickle.encode(python_object)
9 chỉ chứa các chuỗi, vì tất cả các giá trị thuộc tính HTML là chuỗi. Nếu bạn đang chuyển một số, ngày hoặc loại đơn giản khác cho JavaScript của bạn, bạn sẽ cần phải phân tích nó. Ví dụ, hãy tưởng tượng bạn đã vượt qua một số nguyên:

my_cool_js_function(some_param){
    // do some cool stuff
}
9

Bạn có thể muốn

var my_var_parsed = jQuery.parseJSON(my_var);
5 chuyển đổi giá trị này từ một chuỗi:

// some html code

my_cool_js_function({{param}})
0

Right-o.

Không có giới hạn

A

import jsonpickle

context['python_object'] = jsonpickle.encode(python_object)
0 có thể có nhiều thuộc tính dữ liệu như bạn muốn:

// some html code

my_cool_js_function({{param}})
1

Nhưng đến một lúc nào đó, điều này có thể cảm thấy khá khó sử dụng. Ngoài ra, nó không thuận tiện để vượt qua các loại phức tạp như dicts hoặc danh sách trong các thuộc tính. Điều đó dẫn chúng ta đến cửa số hai!

Sử dụng 8 cho các giá trị phức tạp

Nếu bạn cần chuyển một dict hoặc danh sách cho JavaScript, hãy sử dụng bộ lọc Django từ ____38. Ví dụ, hãy tưởng tượng quan điểm của bạn đã vượt qua biến này trong bối cảnh:

// some html code

my_cool_js_function({{param}})
2

Bạn có thể chuyển biến này cho bộ lọc


8 như vậy:

// some html code

my_cool_js_function({{param}})
3

Django sẽ hiển thị thẻ

{{ mydata|json_script:"mydata" }}
0 chứa dữ liệu:

// some html code

my_cool_js_function({{param}})
4

Kịch bản sau đó có thể tìm dữ liệu

import jsonpickle

context['python_object'] = jsonpickle.encode(python_object)
0 làm phần tử tiếp theo sau
import jsonpickle

context['python_object'] = jsonpickle.encode(python_object)
7 bằng cách sử dụng
{{ mydata|json_script:"mydata" }}
3 và phân tích dữ liệu với
{{ mydata|json_script:"mydata" }}
4:

// some html code

my_cool_js_function({{param}})
5

Sweet.

Django <4.1

Hình thức trên của


8 chỉ được hỗ trợ trên Django 4.1+. Trước đó, bạn cần cung cấp cho nó một ID cho dữ liệu
import jsonpickle

context['python_object'] = jsonpickle.encode(python_object)
0, nhưng bạn có thể vượt qua
{{ mydata|json_script:"mydata" }}
7, mà các trình duyệt hiểu như là không có ID ID:

// some html code

my_cool_js_function({{param}})
6

… Kết xuất như:

// some html code

my_cool_js_function({{param}})
7

JavaScript ở trên vẫn sẽ hoạt động, vì nó chỉ sử dụng cấu trúc DOM để tìm dữ liệu

import jsonpickle

context['python_object'] = jsonpickle.encode(python_object)
0.

Alrighty sau đó.

Với một id

Bạn cũng có thể chuyển ID cho


8 cho dữ liệu
import jsonpickle

context['python_object'] = jsonpickle.encode(python_object)
0. Điều này có thể hữu ích nếu JavaScript
import jsonpickle

context['python_object'] = jsonpickle.encode(python_object)
0 của bạn không nằm cạnh dữ liệu của bạn
import jsonpickle

context['python_object'] = jsonpickle.encode(python_object)
0 hoặc nếu một tệp JavaScript nên sử dụng một số dữ liệu
import jsonpickle

context['python_object'] = jsonpickle.encode(python_object)
0S. Ví dụ:

// some html code

my_cool_js_function({{param}})
8

Django làm cho điều này như:

// some html code

my_cool_js_function({{param}})
9

Sau đó, bạn có thể sử dụng


4 để tìm các phần tử
import jsonpickle

context['python_object'] = jsonpickle.encode(python_object)
0 và
{{ mydata|json_script:"mydata" }}
4 một lần nữa để phân tích dữ liệu chứa:


0

Đây là kỹ thuật được đề xuất trong tài liệu


8.

Neat!

Các kỹ thuật không được khuyến khích khác

Dưới đây là một vài lựa chọn khác mà bạn đã thấy, mà tôi không đề xuất.

Sử dụng không an toàn bộ lọc 8

Bạn có thể đã thấy JavaScript được tạo ra sử dụng bộ lọc


8:


1


8 đánh dấu một biến là an toàn cho việc đưa vào HTML, nghĩa là, nó vô hiệu hóa Django tựa HTML Escaping. Điều này sẽ cho phép
const mydata = JSON.parse(document.getElementById('mydata').textContent);
1 xuất hiện không thay đổi trong tập lệnh được tạo ra:


2

Điều này mở ra kịch bản lên rộng để tấn công mặc dù. Hãy tưởng tượng

import jsonpickle

context['python_object'] = jsonpickle.encode(python_object)
1 là:


3

Sau đó, HTML được kết xuất sẽ là:


4

Trình duyệt phân tích cú pháp HTML mà không có bất kỳ nhận thức nào về cú pháp JavaScript, dẫn đến:

  1. Một
    import jsonpickle
    
    context['python_object'] = jsonpickle.encode(python_object)
    
    0 đầu tiên, đóng cửa sau
    const mydata = JSON.parse(document.getElementById('mydata').textContent);
    
    4. Trình duyệt sẽ chạy JavaScript này, sẽ gặp sự cố với một lỗi về chuỗi chưa được giải thích.
  2. Thẻ
    import jsonpickle
    
    context['python_object'] = jsonpickle.encode(python_object)
    
    0 được tiêm lần thứ hai, tải
    const mydata = JSON.parse(document.getElementById('mydata').textContent);
    
    6.
  3. Một nút văn bản có nội dung
    const mydata = JSON.parse(document.getElementById('mydata').textContent);
    
    7
  4. const mydata = JSON.parse(document.getElementById('mydata').textContent);
    
    8 cuối cùng bị bỏ qua, vì nó không phù hợp với
    import jsonpickle
    
    context['python_object'] = jsonpickle.encode(python_object)
    
    0.

Một lần nữa,

const mydata = JSON.parse(document.getElementById('mydata').textContent);
6 có thể đánh cắp tất cả dữ liệu người dùng. Panik !!

Vì vậy, sử dụng


8 như thế này là không an toàn. Nó chỉ an toàn khi sử dụng nó với HTML đã được giới thiệu, ví dụ như từ một đoạn được kết xuất sẵn.

Còn {# DON’T DO THIS #} 2 thì sao?

Có thể mẫu JavaScript với bộ lọc

{# DON’T DO THIS #}
<script>
    const username = "{{ username }}";
script>
2:


5

Điều này có một số sự tinh tế mặc dù, như các tài liệu hiện đang nói:

Điều này không làm cho chuỗi an toàn để sử dụng trong các mẫu HTML hoặc JavaScript

.

Tuy nhiên, có một PR mở để cải thiện các tài liệu. Có vẻ như

{# DON’T DO THIS #}
<script>
    const username = "{{ username }}";
script>
2 đã được làm an toàn trong quá khứ với bản cập nhật tài liệu.

Tuy nhiên, tôi khuyên bạn nên sử dụng các thuộc tính dữ liệu vì:

  1. JavaScript khuôn mẫu vẫn không an toàn: bạn có thể sử dụng các thẻ hoặc bộ lọc khác mà không có rủi ro.

  2. Thuộc tính dữ liệu hoạt động với cả tập lệnh nội tuyến và các tệp tập lệnh riêng biệt. Bạn không cần phải tái cấu trúc bất cứ điều gì nếu bạn chuyển từ tập lệnh nội tuyến sang một tệp riêng.

    (Và sử dụng các tệp tập lệnh riêng biệt là tốt cho các lý do khác, như đã lưu ý trước đây.)

  3. Hiện tại, các tài liệu vẫn nói

    {# DON’T DO THIS #}
    <script>
        const username = "{{ username }}";
    script>
    
    2 không an toàn. Vẫn chưa được sự chấp thuận từ đội an ninh Django hoặc các nghiên cứu sinh.

Vây

Có thể dữ liệu của bạn luôn chuyển nhanh và an toàn cho JavaScript của bạn,

—Adam


Làm cho sự phát triển của bạn dễ chịu hơn với Boost Django DX của bạn.


Một email tóm tắt một tuần, không spam, tôi pinky hứa.

Bài viết liên quan:

  • Cách thiết lập bản đồ nguồn với Django
  • Cách thêm favicon vào trang web Django của bạn

Tags: Django django