2012-08-08 20 views
7

में फ़ंक्शन() के आसपास सैंडबॉक्स बनाएं क्या मैं पैरेंट/ग्लोबल स्कॉप्स में स्ट्रिंग-जेनरेट फ़ंक्शन (फ़ंक्शन कन्स्ट्रक्टर का उपयोग करके) की पहुंच को सीमित कर सकता हूं?जावास्क्रिप्ट

उदाहरण के लिए: निम्न कोड, जैसा कि है, प्रिंट करता है झूठी, क्योंकि फ़ंक्शन चर में एक चर को संग्रहीत/संशोधित कर रहा है।

window.a = 4; 
Function("a=3;")() 
console.log(a === 4); 

मैं खिड़की/माता-पिता गुंजाइश के लिए उपयोग को प्रतिबंधित करने और यह "सही" प्रिंट आउट कर सकते हैं?

उत्तर

5

मुझे ऐसा नहीं लगता है। आप वैश्विक आप मानकों में बचाना चाहते हैं नाम दे सकते हैं ताकि वे उन्हें शैडो:

window.a = 4; 
Function("a", "a=3;")() 
console.log(a === 4); 

लेकिन समारोह चाहे आप कुछ भी कोशिश ... यही कारण है कि यह वैश्विक कहा जाता है है वैश्विक के लिए उपयोग किया जा रहा है।

आप जो करने की कोशिश कर रहे हैं उसके आधार पर, वेब वर्कर्स जैसे अन्य कार्य-आसपास हैं ... और हमेशा के रूप में, hidden iframe hacks

+1

ठीक है, आप 'window' और' document' पैरामीटर के रूप में निर्धारित कर सकते हैं, के लिए सीधी पहुँच को रोकने के लिए: इस तरह से बनाया समारोह आइफ्रेम के वैश्विक गुंजाइश या पृष्ठ की वैश्विक क्षेत्र पर पहुंच है या आसानी से परीक्षण किया जा सकता उन्हें (जैसा कि आपने पहले ही कहा है) और फिर ग्लोबल्स की अंतर्निहित परिभाषा को रोकने के लिए कोड को 'सख्त उपयोग' तैयार करें। यह काम कर सकता है। लेकिन निश्चित रूप से यह मौजूदा ग्लोबल्स तक पहुंच को रोकता नहीं है जब तक कि आप पैरामीटर के माध्यम से उन्हें "छाया" न करें। हो सकता है कि कोई भी सभी 'विंडो' गुणों पर पुन: सक्रिय हो और पैरामीटर सूची स्वचालित रूप से बना सके। –

+0

@ फ़ेलिक्सक्लिंग चेहरे के मूल्य पर अच्छा लगता है, मैं कुछ हैक्स को देखने के लिए कोशिश कर रहा हूं कि क्या मैं अभी भी वैश्विक – Esailija

+0

@ फ़ेलिक्सक्लिंग तक पहुंच प्राप्त कर सकता हूं, मेरा वर्तमान एक है, अगर आप 'फंक्शन' छाया कर सकते हैं तो काम कर सकते हैं http://jsfiddle.net/dFmyd/ – Esailija

2

@ Esailija का जवाब सही है। इसके अतिरिक्त, मैं वैश्विक चर की संख्या को सीमित करने की अनुशंसा करता हूं जिसे आपको पहले स्थान पर रखना है।

var APP = (function() { 
    return { 
     a: 4 
    }; 
}()); 

कोई रास्ता पूरी तरह से वैश्विक क्षेत्र तक पहुँच सीमित करने है, लेकिन कम से कम इस तरह से आप केवल एक वस्तु की रक्षा के लिए की जरूरत है: कुछ भी है कि आप सामान्य रूप से एक APP दायरे में वैश्विक नामस्थान में डाल होता है कि आप नियंत्रित रखो : APP

9

यहां एक अतिरिक्त विचार है जो एस्सेलिया के प्रस्ताव के साथ काफी शक्तिशाली हो सकता है (चर्चा के लिए उनके उत्तर पर टिप्पणियां देखें)।

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

मैं समारोह की कल्पना इस तरह हो सकती है:

function sandboxed(code) { 
    var frame = document.createElement('iframe'); 
    document.body.appendChild(frame); 

    var F = frame.contentWindow.Function, 
     args = Object.keys(frame.contentWindow).join(); 

    document.body.removeChild(frame); 

    return F(args, code)(); 
} 

DEMO

वैकल्पिक रूप से आप कोड को 'use strict'; पहले जोड़ें कर सकते हैं।


यह कम से कम क्रोम में काम करता है।

(function() { 
    var frame = document.createElement('iframe'); 
    document.body.appendChild(frame); 
    var same = window === frame.contentWindow.Function('return window;')(); 
    alert(same ? ':(' : ':)'); 
    document.body.removeChild(frame); 
}()); 
+1

बहुत रचनात्मक: डी +1 मुझे आईई 8 के अलावा '') मिलता है, जहां यह 'संपत्ति का समर्थन नहीं करता है या विधि फंक्शन ' – Esailija

+0

@Esailija: परीक्षण के लिए धन्यवाद (मेरे पास IE नहीं है)। हो सकता है कि iframe के स्रोत को IE में स्पष्ट रूप से सेट किया जाना चाहिए ('frame.src = 'के बारे में: blank'' करना चाहिए) या संपत्ति को अलग-अलग नाम दिया गया है (' contentWindow' नहीं)। यदि आपको स्रोत सेट करना है, तो हो सकता है कि आपको विंडो तक पहुंचने से पहले 'लोड' ईवेंट की प्रतीक्षा करनी पड़े, लेकिन निश्चित रूप से परिणाम के लिए कॉलबैक स्वीकार करने में कोई समस्या नहीं है :) –

+0

हाँ, 'फ्रेम सेट करना एसएससीसी काम करता है। – Esailija