2012-09-09 18 views
18

मैं Jinja2 के साथ HTML से कैसे बचूं ताकि इसे जावास्क्रिप्ट (jQuery) में स्ट्रिंग के रूप में उपयोग किया जा सके?Jinja2 का उपयोग कर जावास्क्रिप्ट के लिए स्ट्रिंग से बचें?

अगर मैं Django के templating प्रणाली उपयोग कर रहे थे मैं लिख सकते हैं:

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

Django के |escapejs filterhtml_string में बातें (जैसे उद्धरण, विशेष वर्ण) है कि इस कोड ब्लॉक के इच्छित उपयोग को तोड़ सकते थे बच जाएगा, लेकिन Jinja2 करता है प्रतीत होता है कि समकक्ष फ़िल्टर नहीं है (क्या मैं यहां गलत हूं?)।

क्या Django से कोड कॉपी/पेस्ट करने से क्लीनर समाधान है?

+0

यहां देखें: http://jinja.pocoo.org/docs/templates/#escaping –

+0

मुझे जिन्जा टैग टेक्स्ट से बचने की आवश्यकता नहीं है, मैं यह सुनिश्चित करने की आवश्यकता है कि 'html_string' में कोई हानिकारक वर्ण नहीं है। – meshy

+0

हो सकता है कि | सुरक्षित फ़िल्टर वह है जो आप इसके बाद हैं: http://flask.pocoo.org/docs/templating/#standard-filters –

उत्तर

7

मुझे पिछले साल इसी तरह की समस्या का सामना करना पड़ा। सुनिश्चित नहीं है कि आप bottle का उपयोग कर रहे हैं, लेकिन मेरे समाधान ने ऐसा कुछ देखा।

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}}) 

(मैं के बाद से मैं इसे हर जगह इस्तेमाल किया एक सहायक समारोह में template_settings dict लिपटे, लेकिन मैं इसे इस उदाहरण में सरल रखा है।)

दुर्भाग्य से, यह एक builtin jinja2 फिल्टर के रूप में सरल नहीं है, लेकिन मैं खुशी से इसके साथ रहने में सक्षम था - विशेष रूप से यह मानते हुए कि मेरे पास जोड़ने के लिए कई अन्य कस्टम फ़िल्टर भी थे।

महत्वपूर्ण नोट: नीचे दी गई अपनी अजीब टिप्पणी के लिए @ मेडमुंड्स को हैट टिप, हमें याद दिलाता है कि json.dumps XSS- सुरक्षित नहीं है। IOW, आप इसे एक उत्पादन, इंटरनेट-फेस सर्वर में उपयोग नहीं करना चाहेंगे। अनुशंसा safer json escape routine लिखना है (या चोरी django's - माफ करना ओपी, मुझे पता है कि आप इससे बचने की उम्मीद कर रहे थे) और json.dumps का उपयोग करने के बजाय कॉल करें।

+0

बिल्कुल सही! मैं बोतल का उपयोग नहीं कर रहा हूं, मैं डेस्कटॉप ऐप बनाने के लिए pywebkitgtk का उपयोग कर रहा हूं, लेकिन 'json.dumps' बिल्कुल वही है जो मुझे चाहिए था। मैं उम्मीद की तुलना में बहुत आसान! धन्यवाद! – meshy

+0

ओह, और बोतल के लिंक के लिए धन्यवाद! मैंने इसे पहले नहीं देखा है, आसानी से आ सकता है;) – meshy

+6

मुझे नहीं लगता कि json.dumps() आपको चिंता करने की ज़रूरत वाली चीज़ों से बच निकलता है। उदा।, जैसा कि वर्तमान में लिखा गया है, 'escapejs ("")' रिटर्न '" "' - ऐसा लगता है कि यह आपके एचटीएमएल में रिसाव करने के लिए एक बंद स्क्रिप्ट टैग (और इसके बाद कुछ भी!) की अनुमति दे सकता है। (Django escapejs फ़िल्टर < and > वर्णों पर यूनिकोड से निकलता है, जो समस्या से बचाता है।) – medmunds

-1

आप जिंजा 2 के autoescape का भी उपयोग कर सकते हैं। तो, उदाहरण के लिए, आप autoescape अपने jinja2 पर्यावरण के लिए अजगर में जोड़ सकते हैं:

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

वैकल्पिक रूप से, आप इस्तेमाल कर सकते हैं Autoescape एक्सटेंशन जिंजा 2.4 में जोड़ा जहां autoescaping HTML में प्रयोग किया जाता है पर अधिक नियंत्रण है करने के लिए। इस here और उदाहरण (Google ऐप इंजन में) here पर अधिक जानकारी।

पायथन:

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

क्या यह सिर्फ मानक HTML से बच नहीं रहा है? प्रश्न जावास्क्रिप्ट के बारे में पूछता है? – pip

+1

नहीं, यह निश्चित रूप से केवल HTML से बच रहा है। –

11

यह एक escapejs फिल्टर, Django के आधार पर है कि मैं Jinja2 टेम्प्लेट में उपयोग के लिए लिखा है:

_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 

उदाहरण टेम्पलेट में सुरक्षित उपयोग:

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

जब variableName str या unicode है।

+0

यह पहले से ही आवश्यक है कि '{{variableName | espacejs}} 'उद्धरण (एकल या डबल) में है इसलिए वर्ग ब्रैकेट की चाल संभव नहीं है। अन्यथा एक जगह भी खतरनाक हो सकती है। – Tometzky

+2

इस उत्तर ने मुझे इस धागे में मदद की। रीयल दिमाग एक स्ट्रिंग के अंदर वर्णों से बचने के लिए बेंडर जो पाइथन से एचटीएमएल में मुद्रित किए जा रहे हैं जो जावास्क्रिप्ट के अंदर उद्धरण टैग के अंदर जा रहा है जो जेएसओएन के रूप में पार्स करने जा रहा है। मदद के लिए Thnx! – Matthisk

2

मैं सिर्फ इस समस्या को शोध किया, मेरे समाधान एक फिल्टर परिभाषित करने के लिए है:

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

और टेम्पलेट में:

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

यह अच्छा विशेषता यह है कि myVar कुछ भी हो सकता है कि JSON-serialized

+4

उपयोगकर्ता द्वारा जेनरेट की गई सामग्री के साथ ऐसा न करें, क्योंकि उपयोगकर्ता जेएस निष्पादित करने में सक्षम होंगे। उदाहरण के लिए जब 'myvar' = '

संबंधित मुद्दे