javascript - atscript - स्क्रिप्टिंग भाषा




मैं उपयोगकर्ता-स्क्रिप्ट के साथ साझा वेब कार्यकर्ता को कैसे लोड कर सकता हूं? (2)

मैं उपयोगकर्ता-स्क्रिप्ट के साथ एक साझा कार्यकर्ता लोड करना चाहता हूं। समस्या यह है कि उपयोगकर्ता-स्क्रिप्ट मुफ़्त है, और किसी फ़ाइल की मेजबानी के लिए कोई व्यवसाय मॉडल नहीं है - और न ही मैं एक सर्वर का उपयोग करना चाहूंगा, यहां तक ​​कि एक मुफ्त, एक छोटी फ़ाइल की मेजबानी करने के लिए भी। भले ही, मैंने इसकी कोशिश की और मुझे (निश्चित रूप से) एक ही मूल नीति त्रुटि मिली:

Uncaught SecurityError: Failed to construct 'SharedWorker': Script at
'https://cdn.rawgit.com/viziionary/Nacho-Bot/master/webworker.js'
cannot be accessed from origin 'http://stackoverflow.com'.

एक कार्यकर्ता को स्ट्रिंग में और फिर एक ब्लॉब में परिवर्तित करके एक वेब वर्कर को लोड करने का एक और तरीका है और उस लोडिंग को कार्यकर्ता के रूप में लेकिन मैंने उसे भी आज़माया:

var sharedWorkers = {};
var startSharedWorker = function(workerFunc){
    var funcString = workerFunc.toString();
    var index = funcString.indexOf('{');
    var funcStringClean = funcString.substring(index + 1, funcString.length - 1);
    var blob = new Blob([funcStringClean], { type: "text/javascript" });
    sharedWorkers.google = new SharedWorker(window.URL.createObjectURL(blob));
    sharedWorkers.google.port.start();
};

और वह भी काम नहीं करता है। क्यों? क्योंकि साझा श्रमिकों को उस स्थान के आधार पर साझा किया जाता है, जहां से उनकी श्रमिक फ़ाइल लोड होती है। चूँकि createObjectURL प्रत्येक उपयोग के लिए एक विशिष्ट फ़ाइल नाम बनाता है , इसलिए श्रमिकों के पास कभी भी एक ही URL नहीं होगा और इसलिए इसे कभी साझा नहीं किया जाएगा।

इस समस्या का समाधान किस प्रकार से किया जा सकता है?

नोट: मैंने विशिष्ट समाधानों के बारे में पूछने की कोशिश की, लेकिन इस बिंदु पर मुझे लगता है कि मैं जो सबसे अच्छा कर सकता हूं, वह समस्या के किसी भी समाधान के लिए अधिक व्यापक तरीके से पूछ सकता है, क्योंकि मेरे सभी मूल समाधान एक ही मूल नीतियों के कारण मौलिक रूप से असंभव लगते हैं। जिस तरह से URL.createObjectURL काम करता है ( ऐनक से , परिणामी फ़ाइल URL को बदलना असंभव लगता है)।

यह कहा जा रहा है, अगर मेरे सवाल को किसी तरह सुधार या स्पष्ट किया जा सकता है, तो कृपया एक टिप्पणी छोड़ दें।


शर्त लगाना

  • जैसा कि आपने शोध किया है और जैसा कि टिप्पणियों में बताया गया है, SharedWorker का URL उसी मूल नीति के अधीन है।
  • इस सवाल के अनुसार Worker के URL के लिए कोई CORS सपोर्ट नहीं है।
  • इस मुद्दे के अनुसार GM_worker समर्थन अब एक WONT_FIX है, और फ़ायरफ़ॉक्स में परिवर्तन के कारण इसे लागू करना असंभव लगता है । एक नोट यह भी है कि सैंडबॉक्स्ड Worker ( unsafeWindow.Worker विपरीत। unsafeWindow.Worker ) या तो काम नहीं करता है।

डिज़ाइन

मुझे लगता है कि आप जो हासिल करना चाहते हैं वह एक @include * जो कुछ आंकड़े एकत्र करेगा या कुछ वैश्विक UI बना देगा जो हर जगह दिखाई देगा। और इस प्रकार आप रनटाइम में कुछ स्टेट या स्टेटिस्टिक एग्रीगेट्स बनाए रखना चाहते हैं (जो यूजर-स्क्रिप्ट के हर उदाहरण से एक्सेस करना आसान होगा), और / या आप कुछ कम्प्यूट-हेवी रूटीन करना चाहते हैं (क्योंकि अन्यथा यह होगा) धीमी गति से लक्षित साइटें)।

किसी भी समाधान के रास्ते में

मैं जो प्रस्ताव देना चाहता हूं उसका समाधान एक विकल्प के साथ SharedWorker डिजाइन को बदलना है।

  • यदि आप साझा कार्यकर्ता में एक राज्य बनाए रखना चाहते हैं, तो केवल Greasemonkey स्टोरेज ( GM_setValue और दोस्तों) का उपयोग करें। यह सभी उपयोगकर्ताओं के उदाहरणों के बीच साझा किया गया है (SQLite दृश्यों के साथ)।
  • यदि आप कुछ गणना-भारी कार्य करना चाहते हैं, तो इसे unsafeWindow.WorkerunsafeWindow.Worker और रिजल्ट को वापस Greasemonkey स्टोरेज में unsafeWindow.Worker
  • यदि आप कुछ पृष्ठभूमि संगणना करना चाहते हैं और इसे केवल एक उदाहरण से चलाया जाना चाहिए, तो "इंटर-विंडो" सिंक्रोनाइज़ेशन लाइब्रेरी की संख्या है (ज्यादातर वे localStorage उपयोग करते हैं, लेकिन ग्रीसेमोमकी का एपीआई समान है, इसलिए इसे लिखना मुश्किल नहीं है। इसके लिए एक एडाप्टर)। इस प्रकार आप एक उपयोगकर्तास्क्रिप्ट इंस्टेंस में लॉक प्राप्त कर सकते हैं और उसमें अपनी दिनचर्या चला सकते हैं। जैसे, IWC या ByTheWay ( संभवतः स्टैक एक्सचेंज पर इसका उपयोग किया जाता है ; इसके बारे में पोस्ट करें )।

अन्य रास्ता

मुझे यकीन नहीं है, लेकिन कुछ सरल प्रतिक्रिया हो सकती है जो SharedWorker हो सकती है, जो SharedWorker से साझा की गई है ताकि आप साझा करना चाहते हैं जैसा कि आप साझा करना चाहते हैं। प्रारंभिक बिंदु इस उत्तर के संपादन में है ।


आप दिए गए Blob से टाइप application/javascript का एक Blob URL बनाने के लिए fetch() , response.blob() का उपयोग कर सकते हैं; SharedWorker() द्वारा बनाए गए Blob URL पैरामीटर; window.open() का उपयोग करें, पहले से मूल window पर परिभाषित समान SharedWorker को परिभाषित करने के लिए नई खुलने वाली window की load घटना, message कार्यक्रम को मूल रूप से SharedWorker को नए खुले window संलग्न करें।

किसी अन्य iFrame से iFrame की सामग्री को कैसे साफ़ करें , इस पर javascript को console पर आज़माया गया था, जहाँ वर्तमान प्रश्न URL को worker.port.postMessage() माध्यम से window खोलने के message साथ नए tab पर लोड किया जाना चाहिए। console पर लॉग ऑन किया गया।

window खोलते समय message घटना को भी लॉग इन करना चाहिए, जब नई खुली window worker.postMessage(/* message */) का उपयोग कर पोस्ट किया गया हो। worker.postMessage(/* message */) , इसी प्रकार window खोलने पर

window.worker = void 0, window.so = void 0;

fetch("https://cdn.rawgit.com/viziionary/Nacho-Bot/master/webworker.js")
  .then(response => response.blob())
  .then(script => {
    console.log(script);
    var url = URL.createObjectURL(script);
    window.worker = new SharedWorker(url);
    console.log(worker);
    worker.port.addEventListener("message", (e) => console.log(e.data));
    worker.port.start();

    window.so = window.open("https://.com/questions/" 
                            + "38810002/" 
                            + "how-can-i-load-a-shared-web-worker-" 
                            + "with-a-user-script", "_blank");

    so.addEventListener("load", () => {
      so.worker = worker;
      so.console.log(so.worker);
      so.worker.port.addEventListener("message", (e) => so.console.log(e.data));
      so.worker.port.start();
      so.worker.port.postMessage("hi from " + so.location.href);
    });

    so.addEventListener("load", () => {
      worker.port.postMessage("hello from " + location.href)
    })

  });

किसी भी tab पर console पर आप तब उपयोग कर सकते हैं, जैसे; वर्तमान URL की नई window में किसी अन्य iFrame worker.postMessage("hello, again") से iFrame की सामग्री को कैसे साफ़ करें मैं उपयोगकर्ता-स्क्रिप्ट के साथ साझा वेब कार्यकर्ता को कैसे लोड कर सकता हूं? , worker.port.postMessage("hi, again"); जहां प्रत्येक window पर message घटनाएँ जुड़ी हुई window , प्रारंभिक URL पर बनाए गए मूल SharedWorker का उपयोग करके दो window बीच संचार प्राप्त किया जा सकता है।






userscripts