क्या मैं iframe में window.location.replace का उपयोग कर सकता हूं?


15

हम इतिहासwindow.location.replace से बचने के लिए, और पेज के रीलोड के बिना ऑन-पेज एंकर को लक्षित करने के लिए उपयोग कर सकते हैं , लेकिन आइफ्रेम में नहीं?

समस्या एक सीएसपी (सामग्री सुरक्षा नीति) उल्लंघन है, जिसे राज्यों script-src 'unsafe-inline'को सक्षम होना चाहिए। सिवाय मेरे पास एक CSP परिभाषित नहीं है, और भले ही मैं एक को परिभाषित करता हूं और अनुमति script-src 'unsafe-inline'देता हूं फिर भी वही उल्लंघन त्रुटि देता है। Ie11 / chrome / ff में समान परिणाम।

एक ही डोमेन (एक ही निर्देशिका में) पर iframe

  1. कंसोल में iframe को लक्षित करें और window.location.replace('/samepage.html#onpage_anchor')कंसोल में उपयोग करें ।
  2. यह काम करता हैं। यह पृष्ठ पर पुनः लोड किए बिना और इतिहास के बिना पृष्ठ लंगर पर लक्षित करता है।
  3. एंकर लिंक पर समान कोड इनलाइन डालें और यह काम करता है।
  4. बाह्य स्क्रिप्ट में समान कोड का उपयोग करें , csp उल्लंघन त्रुटि प्राप्त करें यह एक iframe में नहीं तो ठीक काम करता है।

मैं एक सीएसपी बनाने की कोशिश की कार्रवाई की अनुमति देने के लिए, लेकिन भी नहीं सबसे अनुमोदक सामग्री सुरक्षा नीतियों संभव यह अनुमति होगी।


संपादित करें: इसलिए मैंने प्लंकर पर एक साथ उदाहरण रखे हैं जो कई फाइलों को अनुमति देता है ताकि मैं उचित hrefs का उपयोग कर सकूं जो माता-पिता / बाल पृष्ठों का संदर्भ देते हैं।

प्लंकर उदाहरण के बारे में नोट्स:

  1. इन उदाहरणों में समस्या को पुन: प्रस्तुत नहीं किया गया है। स्क्रिप्ट पूरी तरह से काम करता है, यहां तक ​​कि iframe में भी। हालाँकि, समान कोड मेरे स्थानीय सर्वर पर काम नहीं करता है, या जब मैं इसे चलाता हूं तो यह VPS पर लाइव होता है।

  2. मुझे संदेह है कि CSP उल्लंघन प्लंकर पर ट्रिगर नहीं होता है क्योंकि प्लंकर ब्राउज़र को किसी प्रकार की अमूर्त परत के माध्यम से सामग्री प्रस्तुत कर रहा है।

  3. पहली बार जब आप पैरेंट में लिंक लिंक पर क्लिक करते हैं, तो यह रिफ्रेश का कारण बनता है। इसका कारण यह है कि जिस तरह से पेज शुरू में लोड होता है वह संदर्भ index.html नहीं है। पृष्ठ के पुनः लोड के बिना अपेक्षित क्लिक्स काम करते हैं। Iframe में कोई समस्या नहीं है क्योंकि यह प्रारंभ में child.html को संदर्भित करता है

  4. कोड को दिखाने के लिए इसे काम करने की आवश्यकता के बिना कोड को दिखाने के लिए ये अच्छे उदाहरण हैं (जैसा कि नीचे उल्लेखित स्टैकवॉयरफ्लो स्निपेट्स में काम करने के लिए hrefs को बदलने की आवश्यकता है)। यह भी अच्छा है क्योंकि यह जावास्क्रिप्ट को काम करना दिखाता है जैसा कि इसे करना चाहिए। लेकिन यह वास्तव में समस्या नहीं दिखाता है। वास्तविक समस्या को देखने के लिए आपको अपने संपादक में इसे लोड करने और स्थानीय सर्वर या लाइव होस्टिंग वातावरण पर चलाने की आवश्यकता होगी।

प्लंकर उदाहरण

स्क्रिप्ट के साथ: स्क्रिप्ट के बिना इतिहास
: इतिहास के साथ


सरलीकृत कोड उदाहरण

एक प्रविष्टि के साथ सरल समझौते। समस्या को पुन: पेश करने के लिए पर्याप्त है।

खुले / बंद पर क्लिक करने से विस्तार / पतन समझौते का विस्तार होगा, जेएस की आवश्यकता नहीं है। जेएस को सटीक काम करना चाहिए लेकिन इतिहास के बिना। ठीक काम करता है, लेकिन एक iframe में नहीं।

कोड स्निपेट नोट:

  1. आप स्निपेट चला सकते हैं कि मैं क्या वर्णन कर रहा हूं, इसके बारे में पता करने के लिए, लेकिन यह वास्तव में मुद्दे को प्रदर्शित नहीं करता है।

  2. स्निपेट वास्तविक ब्राउज़र में ऐसा व्यवहार नहीं करता है, जावास्क्रिप्ट काम नहीं करता है।

  3. स्निपेट कोड दिखाता है, लेकिन इसे समस्या को देखने के लिए एक iframe में चलाया जाना चाहिए। अंतर देखने के लिए इसे आइफ्रेम के बाहर चलाएं और यह कैसे काम करना चाहिए।

  1. जेएस के साथ लिंक कैसे काम करते हैं (पूरे यूआरएल को बदलने के लिए) वे वास्तव में स्निपेट में दिखाई देने के बजाय ऐसा होना चाहिए (स्निपेट में वास्तविक HTML पृष्ठ को लक्षित नहीं कर सकते)। इसलिए यदि आप अपने संपादक में यह कोशिश करते हैं (कृपया करें), तो इस प्रारूप के लिंक बदलने के लिए याद रखें ताकि वे अभी भी एक ही पेज एंकर हैं, लेकिन पेज . html लिंक में शामिल है।href="https://stackoverflow.com/thispage.html#ac1"href="#ac1" this_document.html#anchor


लिपी

$(document).ready(function() {

      // anchor links without history
      $.acAnch = function(event) {
        event.preventDefault();
        var anchLnk = $(event.target);
        var anchTrgt = anchLnk.attr('href');
        window.location.replace(anchTrgt);
      }
      // listen for anchor clicks
      $('.accordion').on('click', 'a', $.acAnch);

    });

यह बहुत सरल है:
1. acAchch फ़ंक्शन लेता हैhref विशेषता और इसे इसमें छोड़ देता है window.location.replace()
2. acAnch फ़ंक्शन को चलाने के लिए समझौते के भीतर एंकर पर क्लिक के लिए सुनो।

इसलिए सभी स्क्रिप्ट को चलाया जाता है window.location.replace('/this_same_page.html#on_page_anchor')

यदि आप उस कंसोल में काम करते हैं, तो कोई CSP उल्लंघन नहीं करता है। लेकिन बाहरी स्क्रिप्ट से इसे चलाने से काम नहीं चलता।

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

onclick="event.preventDefault();window.location.replace('/thispage.html#acc0');"
onclick="event.preventDefault();window.location.replace('/thispage.html#acc1');"

यह कहते हुए कि संबंधित लिंक पूरी तरह से काम करते हैं , लेकिन मैं वास्तव में इनलाइन स्क्रिप्ट का उपयोग नहीं करना पसंद करता हूं बाहरी स्क्रिप्ट के साथ ऐसा करने का एक तरीका होना चाहिए

मैंने iframe के बजाय माता-पिता पर जावास्क्रिप्ट चलाने की कोशिश की (संशोधनों के साथ पाठ्यक्रम के बच्चे के भीतर लिंक का चयन करने के लिए)। समान CSP त्रुटि परिणाम।


मैं यह क्यों कर रहा हूँ?

वैसे साइट उदाहरण की तुलना में बहुत अधिक जटिल है। इफराम में एंकर ठीक काम करते हैं लेकिन वे इतिहास को जोड़ते हैं।यदि आप जावास्क्रिप्ट के बिना ऊपर दिए गए कोड को चलाते हैं, (या सिर्फ स्निपेट चलाते हैं), तो अकॉर्डियन को कुछ बार खोलें और बंद करें, और बैक बटन का उपयोग करें, यह ओपन क्लोज स्टेट्स के माध्यम से वापस जाएगा।

मैं इतिहास को बुरा नहीं मानूंगा, लेकिन अगर यह आईफ्रेम में है, जब आप मूल पृष्ठ को छोड़ देते हैं और फिर वापस आते हैं, तो आइफ्रेम का इतिहास टूट जाता है। वापस जाना अब समझौते राज्यों के माध्यम से वापस नहीं जाता है, लेकिन इसके बजाय सिर्फ iframe को फिर से लोड करता रहता है। प्रारंभ में एंकरों को iframe reloads का कारण नहीं बनता है, लेकिन बस accordion राज्य के इतिहास के माध्यम से कदम होता है, जो ठीक काम करता है, जब तक आप पृष्ठ को छोड़ कर वापस नहीं आते हैं। फिर वापस समझौते के राज्यों के माध्यम से नहीं जाता है, लेकिन बस समान आइफ्रेम रीलोड के ढेर से गुजरता है यह बहुत ही उपयोगकर्ता के अनुकूल व्यवहार है।

अगर कोई अन्य विधि काम करेगी तो मुझे location.replace का उपयोग करने की आवश्यकता नहीं है। मैंने हालांकि कई अन्य तरीकों की कोशिश की है, और मैंने पाया है कि वे विधियां जो समान परिणाम प्राप्त कर सकती हैं, आम तौर पर समान त्रुटि होती हैं।

लक्ष्य बस रीलोडिंग के बिना पृष्ठ पर एंकर लिंक को सक्रिय करना है, और इतिहास के बिना, एक आइफ्रेम के अंदर।

इनलाइन स्क्रिप्ट काम करती है। क्या हम इसे बाहरी .js फ़ाइल में काम कर सकते हैं?


क्या आप एंकर तक पहुंचने की कोशिश कर रहे हैं? यदि ऐसा है, तो <a href="#ac0" class="ac-close">Close</a>काम करना चाहिए।
डिमेंटिक

ठीक है, मैं प्लंकर पर उदाहरण देता हूं। दुर्भाग्य से, समस्या को प्लंकर पर पुन: प्रस्तुत नहीं किया गया है। बल्कि, इफ्रेम में भी स्क्रिप्ट ठीक काम करती है। स्क्रिप्ट के साथ - कोई इतिहास नहीं है और स्क्रिप्ट के बिना इतिहास है । प्लंकर पर मामूली मुद्दा; माता-पिता के संबंध लिंक के कारण पृष्ठ ताज़ा होता है, केवल पहली बार क्लिक किया गया (प्रारंभ में index.html संदर्भ के बिना प्लंक लोड होता है, इसलिए पहली क्लिक के बाद, यह पृष्ठ पुन: लोड किए बिना अपेक्षित रूप से काम करता है)। Iframe के लिए कोई समस्या नहीं है क्योंकि यह child.html src के साथ लोड है।
वेनेसेम टायरस

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

1
मैंने आपका नमूना कोड अपने सर्वर पर ले लिया, यह ठीक काम कर रहा है, तो मैंने आपके उदाहरण plnkr.co/edit/V3kx7LQbTppaQ6V06uZp?p.preview से एक नया प्लंकर उदाहरण बनाया है। यह भी ठीक काम कर रहा है। कोई CSP त्रुटि परिणाम नहीं।
विचारक

हाँ, अच्छी तरह से यह प्लंकर पर ठीक काम करता है जो मैंने भी किया था। मैं उत्सुक हूं कि यह आपके सर्वर पर कैसे काम करता है, क्योंकि आपकी टिप्पणी के बाद मैंने ट्रिपल की जाँच की और मुझे यह मेरे लाइव सर्वर पर या मेरे स्थानीय सर्वर पर काम करने के लिए नहीं मिला।
वेनेसेम टायरस

जवाबों:



0

आप html iframe टैग के बजाय CSS का उपयोग कर सकते हैं क्योंकि html में iframe टैग हटा दिया गया है


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