2012-09-09 33 views
18

Làm cách nào để thoát HTML bằng Jinja2 để nó có thể được sử dụng như một chuỗi trong JavaScript (jQuery)?Chuỗi thoát cho JavaScript bằng Jinja2?

Nếu tôi được sử dụng hệ thống khuôn mẫu của Django tôi có thể viết:

$("#mydiv").append("{{ html_string|escapejs }}"); 

của Django |escapejs filter sẽ thoát khỏi mọi thứ trong html_string (ví dụ như báo giá, ký tự đặc biệt) có thể phá vỡ các mục đích sử dụng của khối mã này, nhưng Jinja2 làm dường như không có bộ lọc tương đương (tôi có sai ở đây không?).

Có giải pháp nào sạch hơn là sao chép/dán mã từ Django không?

+0

Xem tại đây: http://jinja.pocoo.org/docs/templates/#escaping –

+0

Tôi không cần phải thoát khỏi văn bản thẻ jinja, tôi cần đảm bảo rằng 'html_string' không chứa bất kỳ ký tự độc hại nào. – meshy

+0

Có lẽ bộ lọc an toàn là những gì bạn đang theo sau: http://flask.pocoo.org/docs/templating/#standard-filters –

Trả lời

7

Tôi đã gặp phải sự cố tương tự vào năm ngoái. Không chắc chắn liệu bạn có đang sử dụng bottle hay không, nhưng giải pháp của tôi trông giống như thế này.

import json 

def escapejs(val): 
    return json.dumps(str(val)) # *but see [Important Note] below to be safe 

@app.route('/foo') 
def foo(): 
    return bottle.jinja2_template('foo', template_settings={'filters': {'escapejs': escapejs}}) 

(Tôi quấn template_settings dict trong một hàm helper kể từ khi tôi sử dụng nó ở khắp mọi nơi, nhưng tôi giữ nó đơn giản trong ví dụ này).

Thật không may, nó không đơn giản như một bộ lọc jinja2 dựng sẵn, nhưng Tôi đã có thể sống với nó một cách hạnh phúc - đặc biệt là xem xét rằng tôi đã có một số bộ lọc tùy chỉnh khác để thêm, quá.

Lưu ý quan trọng: Mẹo dành cho @ medmunds để nhận xét tuyệt vời của mình bên dưới, nhắc nhở chúng tôi rằng json.dumps không phải là XSS an toàn. IOW, bạn sẽ không muốn sử dụng nó trong một máy chủ sản xuất với Internet. Khuyến nghị là viết một safer json escape routine (hoặc ăn cắp của django - xin lỗi OP, tôi biết bạn đã hy vọng để tránh điều đó) và gọi đó thay vì sử dụng json.dumps.

+0

Hoàn hảo! Tôi không sử dụng chai, tôi đang sử dụng pywebkitgtk để tạo ứng dụng dành cho máy tính để bàn, nhưng 'json.dumps' chính xác là những gì tôi cần. Đơn giản hơn nhiều so với tôi hy vọng! Cảm ơn bạn! – meshy

+0

Ồ, và cảm ơn cho các liên kết để chai! Tôi đã không nhìn thấy điều đó trước đây, có thể có ích;) – meshy

+6

Tôi không nghĩ rằng json.dumps() thoát khỏi mọi thứ bạn cần phải lo lắng. Ví dụ, như hiện đang được viết, 'escapejs (" ")' trả về '" "' - có vẻ như nó có thể cho phép một thẻ script đóng (và bất kỳ thứ gì sau đó!) Để rò rỉ vào html của bạn. (Bộ lọc Django escapejs làm unicode thoát trên các ký tự < and >, tránh được vấn đề.) – medmunds

-1

Bạn cũng có thể sử dụng số autoescape của jinja2. Vì vậy, ví dụ, bạn có thể thêm autoescape tới Môi trường jinja2 của bạn bằng Python:

JINJA_ENVIRONMENT = jinja2.Environment(
    loader=jinja2.FileSystemLoader(os.path.dirname(__file__)), 
    autoescape=True) 

Ngoài ra, bạn có thể sử dụng mở rộng Autoescape thêm vào trong Jinja 2.4 có quyền kiểm soát nhiều hơn vị trí các autoescaping được sử dụng trong HTML. Thông tin thêm về số điện thoại here và ví dụ này (trong Google App Engine) here.

Python:

JINJA_ENVIRONMENT = jinja2.Environment(
    loader=jinja2.FileSystemLoader(os.path.dirname(__file__)), 
    extensions=['jinja2.ext.autoescape']) 

HTML:

{% autoescape true %} 
    <html> 
     <body> 
      {{ IWillBeEscaped }} 
     </body> 
    </html> 
{% endautoescape %} 
+1

Đây có phải là HTML tiêu chuẩn không? Câu hỏi đặt ra về Javascript? – pip

+1

Không, chắc chắn HTML chỉ thoát. –

11

Đây là một bộ lọc escapejs, dựa trên Django của một người, mà tôi đã viết để sử dụng trong Jinja2 mẫu:

_js_escapes = { 
     '\\': '\\u005C', 
     '\'': '\\u0027', 
     '"': '\\u0022', 
     '>': '\\u003E', 
     '<': '\\u003C', 
     '&': '\\u0026', 
     '=': '\\u003D', 
     '-': '\\u002D', 
     ';': '\\u003B', 
     u'\u2028': '\\u2028', 
     u'\u2029': '\\u2029' 
} 
# Escape every ASCII character with a value less than 32. 
_js_escapes.update(('%c' % z, '\\u%04X' % z) for z in xrange(32)) 
def jinja2_escapejs_filter(value): 
     retval = [] 
     for letter in value: 
       if _js_escapes.has_key(letter): 
         retval.append(_js_escapes[letter]) 
       else: 
         retval.append(letter) 

     return jinja2.Markup("".join(retval)) 
JINJA_ENVIRONMENT.filters['escapejs'] = jinja2_escapejs_filter 

Ví dụ sử dụng an toàn trong một mẫu:

<script type="text/javascript"> 
<!-- 
var variableName = "{{ variableName | escapejs }}"; 
… 
//--> 
</script> 

Khi variableName là str hoặc unicode.

+0

Nó đã được yêu cầu rằng '{{variableName | espacejs}} 'là dấu ngoặc kép (đơn hoặc đôi) nên không thể thực hiện các dấu ngoặc vuông. Nếu không, ngay cả một không gian cũng có thể nguy hiểm. – Tometzky

+2

Câu trả lời này đã giúp tôi trong chủ đề này. Thực tế tâm trí bender để thoát khỏi các ký tự bên trong một chuỗi mà sẽ được in từ Python sang HTML mà sẽ được bên trong các thẻ quote bên trong JavaScript mà sẽ phân tích cú pháp như JSON. Thnx để được giúp đỡ! – Matthisk

2

tôi chỉ nghiên cứu vấn đề này, giải pháp của tôi là để xác định một bộ lọc:

from flask import Flask, Markup 
app = Flask(__name__) 
app.jinja_env.filters['json'] = lambda v: Markup(json.dumps(v)) 

và trong mẫu:

<script> 
var myvar = {{myvar|json}} ; 
</script> 

này có tính năng tốt đẹp mà myvar có thể bất cứ điều gì có thể được JSON-serialized

+4

Đừng làm điều này với nội dung do người dùng tạo, vì người dùng sẽ có thể thực thi JS. Ví dụ: khi cảnh báo 'myvar' ='

Các vấn đề liên quan