आंशिक रेंडर करने से पहले एस्केप_जवास्क्रिप्ट क्यों?


120

मैं इस रेलकास्ट एपिसोड को देख रहा हूं और सोच रहा हूं कि यहां कॉल escape_javascriptकी आवश्यकता क्यों है:

$("#reviews").append("<%= escape_javascript(render(:partial => @review)) %>");

किसके लिए escape_javascriptप्रयोग किया जाता है?

रेल डॉक्स के अनुसार :

escape_javascript (जावास्क्रिप्ट)

भागने वाले वाहक रिटर्न और जावास्क्रिप्ट सेगमेंट के लिए सिंगल और डबल कोट्स।

लेकिन यह मेरे लिए बहुत मायने नहीं रखता है।


23
FYI करें, यहाँ स्वीकृत उत्तर सही उत्तर नहीं है। किकिटो का है
स्टीव

जवाबों:


-3

क्योंकि आप उपयोगकर्ताओं को जावास्क्रिप्ट पोस्ट नहीं करना चाहते हैं जो ब्राउज़र वास्तव में निष्पादित करता है?


4
लेकिन जब आप जावास्क्रिप्ट कोड को पास और रेंडर करना चाहते हैं तो कैसा रहेगा?
बर्टो77

हाँ, वास्तव में यह एक प्रारूपण विधि से अधिक है। यह उपयोगकर्ताओं को अपनी जावास्क्रिप्ट निष्पादित करने से नहीं रोकता है। कुछ भी नहीं रोक सकता है।
लासगनाएन्ड्रोइड

3
यह मददगार नहीं है। इसके बजाय किकिटो का जवाब देखें ।
नितास

363

यह समझना आसान है कि क्या आप कोड को दो भागों में विभाजित करते हैं।

पहला भाग $("#reviews").append("<%= ... %>");erb के साथ जावास्क्रिप्ट है। इसका मतलब यह है कि इसके <%= ... %>अंदर जो भी रूबी कोड होगा, उसे बदल दिया जाएगा। उस प्रतिस्थापन का परिणाम मान्य जावास्क्रिप्ट होना चाहिए, अन्यथा जब ग्राहक इसे संसाधित करने का प्रयास करता है तो यह एक त्रुटि फेंक देगा। तो यह पहली बात है: आपको वैध जावास्क्रिप्ट की आवश्यकता है

एक और बात ध्यान में रखना है कि जो भी रूबी उत्पन्न होता है, उसे दोहरे उद्धरण चिह्नों के साथ जावास्क्रिप्ट स्ट्रिंग के अंदर समाहित किया जाना चाहिए - को दोहरे उद्धरण चिह्नों पर ध्यान दें <%= ... %>। इसका मतलब यह है कि उत्पन्न जावास्क्रिप्ट इस तरह दिखेगा:

$("#reviews").append("...");

अब चलो अंदर माणिक भाग की जांच करते हैं <%= ... %>। क्या करता render(:partial => @review)है? यह एक आंशिक प्रतिपादन कर रहा है - जिसका अर्थ है कि यह किसी भी प्रकार का कोड प्रदान कर सकता है - html, css ... या इससे भी अधिक जावास्क्रिप्ट!

तो, क्या होता है अगर हमारे आंशिक में कुछ सरल html शामिल हैं, जैसे यह एक?

<a href="/mycontroller/myaction">Action!</a> 

याद रखें कि आपकी जावास्क्रिप्ट एक पैरामीटर के रूप में दोहरे-उद्धृत स्ट्रिंग ले रही थी? यदि हम बस <%= ... %>उस आंशिक के कोड के साथ प्रतिस्थापित करते हैं , तो हमारे पास एक समस्या है - href=एक दोहरे उद्धरण के तुरंत बाद ! जावास्क्रिप्ट मान्य नहीं होगी:

// Without escaping, you get a broken javascript string at href
$("#reviews").append("<a href="/mycontroller/myaction">Action!</a>");

ऐसा न हो, इसके लिए आप इन विशेष वर्णों से बचना चाहते हैं, ताकि आपका तार न कटे - इसके लिए आपको कुछ ऐसा चाहिए, जो इसे उत्पन्न करे:

<a href=\"/mycontroller/myaction\">Action!</a>

यह क्या escape_javascriptकरता है यह सुनिश्चित करता है कि लौटा हुआ स्ट्रिंग जावास्क्रिप्ट को "ब्रेक" नहीं करेगा। यदि आप इसका उपयोग करते हैं, तो आपको वांछित आउटपुट मिलेगा:

$("#reviews").append("<a href=\"/mycontroller/myaction\">Action!</a>")

सादर!


4
वास्तव में, बहुत अच्छा स्पष्टीकरण धन्यवाद। मुझे लगता है कि 'एस्केप_जैवस्क्रिप्ट' का उपयोग करना भ्रामक है क्योंकि हम वास्तव में इसका उपयोग वास्तविक जावास्क्रिप्ट से बचने के लिए नहीं कर रहे हैं। आप आंशिक में एक स्क्रिप्ट टैग डाल सकते हैं और किसी भी जावास्क्रिप्ट को निष्पादित कर सकते हैं जो आप चाहते हैं।
स्टीव

13
@Steve सहमत, एक बेहतर नाम होगा escape_for_javascript, क्योंकि अक्सर आप अन्य कोड (उदाहरण के लिए HTML) से बच रहे हैं ताकि यह जावास्क्रिप्ट को तोड़ न जाए।
किकिटो

14
escape_javascript()अब एक छोटी विधि है: सरल j()(रेल में कम से कम 4)।
mjnissim

@kikito, इस आशय का उपयोग करके मुझे एक html आंशिक रेंडर करने की कोशिश कर रहा है जिसमें एक दूरस्थ रूप है? मैं यह पता लगाने की कोशिश कर रहा हूं कि जावास्क्रिप्ट के साथ एक आंशिक प्रतिपादन क्यों शामिल है जिसमें एक और रूप शामिल है जो जावास्क्रिप्ट के माध्यम से सबमिट करेगा दूसरा js के बजाय html होने का अनुरोध करता है। यदि आपके पास समय है, तो क्या आप कृपया इस प्रश्न को देख सकते हैं जो मैंने पहले ही इस बारे में पोस्ट कर दिया है? धन्यवाद! मेरा सवाल
जेक स्मिथ

1
@ जेकस्मिथ ने आपके सवाल का जवाब दिया
किकिटो

8

उपयोगकर्ता दुर्भावनापूर्ण कोड (दुर्भावनापूर्ण उपयोगकर्ता) पोस्ट कर सकते हैं कि यदि शेष छोड़ दिया गया तो संभावित रूप से निष्पादित हो जाएगा, जिससे उपयोगकर्ता आपके आवेदन को नियंत्रित कर सकेंगे।

इसे इस्तेमाल करे:

<% variable = '"); alert("hi there' %>
$("#reviews").append("<%= variable %>");

रेल के वाक्यविन्यास से वास्तव में परिचित नहीं हैं, लेकिन यदि आप बच नहीं जाते हैं, variableतो एक चेतावनी बॉक्स दिखाई देगा, और मुझे नहीं लगता कि इसका उद्देश्य व्यवहार है।


8

यदि आप यहां स्रोत को देखते हैं , तो यह बहुत स्पष्ट होगा।

यह कार्य निम्नलिखित दो चीजों को पूरा करता है:

  1. यह JS_ESCAPE_MAP में परिभाषित लोगों के साथ इनपुट स्ट्रिंग के वर्णों को प्रतिस्थापित करता है

    इसका उद्देश्य यह सुनिश्चित करना है कि जावास्क्रिप्ट कोड को बाहरी स्ट्रिंग के साथ हस्तक्षेप किए बिना सही ढंग से क्रमबद्ध किया गया है जिसके भीतर इसे एम्बेड किया जा रहा है। उदाहरण के लिए यदि आपके पास दोहरे उद्धरण में एक जावास्क्रिप्ट स्ट्रिंग है, तो कोड को तोड़ने से बचाने के लिए स्ट्रिंग शाब्दिक के लिए सभी उद्धरण एकल उद्धरण में होने चाहिए।

  2. फ़ंक्शन यह भी जांचता है कि क्या परिणामी स्ट्रिंग html सुरक्षित है। यदि यह नहीं है, तो यह सुनिश्चित करने के लिए आवश्यक भागने करता है कि स्ट्रिंग html सुरक्षित हो जाए और परिणाम लौटाए।

जब आप भागने_जैवास्क्रिप्ट का उपयोग कर रहे हैं, तो यह आमतौर पर दूसरे स्ट्रिंग के भीतर या मौजूदा HTML को गतिशील रूप से एम्बेड किया जा रहा है। आपको यह सुनिश्चित करने की आवश्यकता है कि ऐसा करने से आपका पूरा पृष्ठ रेंडर नहीं होगा।

इस प्रतिक्रिया के कुछ पहलुओं को अन्य प्रतिक्रियाओं में बताया गया था, लेकिन मैं सभी वस्तुओं को एक साथ लाना चाहता था जिसमें जावास्क्रिप्ट भागने और HTML भागने के बीच का अंतर शामिल है। इसके अलावा, कुछ प्रतिक्रियाएँ स्पष्ट हैं कि यह फ़ंक्शन स्क्रिप्ट इंजेक्शन से बचने में मदद करता है। मुझे नहीं लगता कि यह इस समारोह का उद्देश्य है। उदाहरण के लिए, आपकी समीक्षा में यदि आपकी समीक्षा में सतर्कता ('हाय हाय') है, तो इसे नोड में जोड़ने से पॉप-अप नहीं होगा। आप इसे एक फ़ंक्शन के भीतर एम्बेड नहीं कर रहे हैं जो पृष्ठ लोड या किसी अन्य घटना के माध्यम से चालू हो जाता है। आपके html के भाग के रूप में सचेत रूप से सचेत रहने ('hi there') का अर्थ यह नहीं है कि यह जावास्क्रिप्ट के रूप में निष्पादित होगा।

कहा कि मैं इनकार नहीं कर रहा हूं कि स्क्रिप्ट इंजेक्शन संभव नहीं है। लेकिन इससे बचने के लिए आपको उपयोगकर्ता डेटा लेते समय कदम उठाने और अपने डेटाबेस में संग्रहीत करने की आवश्यकता होती है। आपके द्वारा प्रदान किए जा रहे फ़ंक्शन और उदाहरण जानकारी को रेंडर करने से संबंधित हैं, जो पहले से ही सहेजा गया था।

मुझे उम्मीद है कि यह आपके प्रश्न का उत्तर देने में मदद करता है।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.