কোনও সামগ্রীর স্ক্রিপ্ট ব্যবহার করে পৃষ্ঠা প্রসঙ্গে কোড োকান


480

আমি ক্রোম এক্সটেনশানগুলি কীভাবে তৈরি করব তা শিখছি। আমি সবেমাত্র ইউটিউব ইভেন্টগুলি ধরার জন্য একটি বিকাশ শুরু করেছি। আমি এটি ইউটিউব ফ্ল্যাশ প্লেয়ারের সাথে ব্যবহার করতে চাই (পরে আমি এটি এইচটিএমএল 5 এর সাথে সামঞ্জস্যপূর্ণ করার চেষ্টা করব)।

manifest.json টি:

{
    "name": "MyExtension",
    "version": "1.0",
    "description": "Gotta catch Youtube events!",
    "permissions": ["tabs", "http://*/*"],
    "content_scripts" : [{
        "matches" : [ "www.youtube.com/*"],
        "js" : ["myScript.js"]
    }]
}

myScript.js:

function state() { console.log("State Changed!"); }
var player = document.getElementById("movie_player");
player.addEventListener("onStateChange", "state");
console.log("Started!");

সমস্যাটি হ'ল কনসোলটি আমাকে "শুরু!" , তবে কোনও "রাষ্ট্র পরিবর্তিত!" আমি যখন ইউটিউব ভিডিও খেলি / থামি।

এই কোডটি কনসোলে রাখলে এটি কার্যকর হয়েছিল। আমি কি ভুল করছি?


14
আপনার ফাংশন নামের আশেপাশের উদ্ধৃতিগুলি সরিয়ে দেওয়ার চেষ্টা করুন:player.addEventListener("onStateChange", state);
এডুয়ার্ডো

2
এটিও উল্লেখযোগ্য যে ম্যাচগুলি লেখার সময়, অন্তর্ভুক্ত করতে ভুলবেন না https://বা http://, এটি www.youtube.com/*আপনাকে এক্সটেনশন প্যাক করতে দেয় না এবং মিসিং স্কিম বিভাজনকারী ত্রুটি
নিলে বিশ্বকর্মা

উত্তর:


874

সামগ্রীর স্ক্রিপ্টগুলি "বিচ্ছিন্ন বিশ্বের" পরিবেশে কার্যকর করা হয় । আপনাকে নিজের state()পদ্ধতিটি পৃষ্ঠাতে ইনজেক্ট করতে হবে।

আপনি যখন chrome.*স্ক্রিপ্টের কোনও একটি API ব্যবহার করতে চান , আপনাকে একটি বিশেষ ইভেন্ট হ্যান্ডলারটি প্রয়োগ করতে হবে, এই উত্তরে বর্ণিত হিসাবে: ক্রোম এক্সটেনশন - Gmail এর মূল বার্তাটি পুনরুদ্ধার করা

অন্যথায়, যদি আপনাকে chrome.*এপিআই ব্যবহার করতে না হয় , তবে আমি দৃ strongly়ভাবে একটি <script>ট্যাগ যুক্ত করার মাধ্যমে পৃষ্ঠায় আপনার সমস্ত জেএস কোডটি ইনজেক্ট করার পরামর্শ দিচ্ছি :

সুচিপত্র

  • পদ্ধতি 1: অন্য একটি ফাইল ইনজেক্ট করুন
  • পদ্ধতি 2: এম্বেড কোডটি ইনজেক্ট করুন
  • পদ্ধতি 2 বি: একটি ফাংশন ব্যবহার করে
  • পদ্ধতি 3: একটি ইনলাইন ইভেন্ট ব্যবহার করা
  • ইনজেকশন কোডটিতে গতিশীল মান

পদ্ধতি 1: অন্য একটি ফাইল ইনজেক্ট করুন

আপনার প্রচুর কোড থাকলে এটি সবচেয়ে সহজ / সেরা পদ্ধতি। আপনার এক্সটেনশনের মধ্যে একটি ফাইলে আপনার আসল জেএস কোড অন্তর্ভুক্ত করুন, বলুন script.js। তারপরে আপনার কন্টেন্ট স্ক্রিপ্টটি নীচের মতো হতে দিন (এখানে ব্যাখ্যা করা হয়েছে: গুগল কোম "অ্যাপ্লিকেশন শর্টকাট" কাস্টম জাভাস্ক্রিপ্ট ):

var s = document.createElement('script');
// TODO: add "script.js" to web_accessible_resources in manifest.json
s.src = chrome.runtime.getURL('script.js');
s.onload = function() {
    this.remove();
};
(document.head || document.documentElement).appendChild(s);

দ্রষ্টব্য: আপনি যদি এই পদ্ধতিটি ব্যবহার করেন তবে ইঞ্জেকশন করা script.jsফাইলটি "web_accessible_resources"বিভাগে ( উদাহরণ ) যুক্ত করতে হবে । আপনি যদি তা না করেন তবে Chrome আপনার স্ক্রিপ্টটি লোড করতে অস্বীকার করবে এবং কনসোলে নিম্নলিখিত ত্রুটিটি প্রদর্শন করবে:

ক্রোম-এক্সটেনশনের লোডকে অস্বীকার করা হচ্ছে: // [এক্সটেনশিয়ান্ড] /script.js। এক্সটেনশনের বাইরের পৃষ্ঠাগুলি দ্বারা লোড করার জন্য সংস্থানগুলি অবশ্যই ওয়েব_অ্যাক্সেসযোগ্য_সোর্স ম্যানিফেস্ট কীতে তালিকাবদ্ধ থাকতে হবে।

পদ্ধতি 2: এম্বেড কোডটি ইনজেক্ট করুন

আপনি কোডের একটি ছোট অংশটি দ্রুত চালাতে চাইলে এই পদ্ধতিটি কার্যকর is (আরও দেখুন: ক্রোম এক্সটেনশান সহ ফেসবুক হটকি কীভাবে অক্ষম করবেন? )

var actualCode = `// Code here.
// If you want to use a variable, use $ and curly braces.
// For example, to use a fixed random number:
var someFixedRandomValue = ${ Math.random() };
// NOTE: Do not insert unsafe variables in this way, see below
// at "Dynamic values in the injected code"
`;

var script = document.createElement('script');
script.textContent = actualCode;
(document.head||document.documentElement).appendChild(script);
script.remove();

দ্রষ্টব্য: টেমপ্লেট লিটারেলগুলি কেবলমাত্র ক্রম 41 এবং তারপরে সমর্থিত। আপনি যদি ক্রম 40- এ এক্সটেনশনটি কাজ করতে চান তবে ব্যবহার করুন:

var actualCode = ['/* Code here. Example: */' + 'alert(0);',
                  '// Beware! This array have to be joined',
                  '// using a newline. Otherwise, missing semicolons',
                  '// or single-line comments (//) will mess up your',
                  '// code ----->'].join('\n');

পদ্ধতি 2 বি: একটি ফাংশন ব্যবহার করে

কোডের একটি বড় অংশের জন্য, স্ট্রিংটির উদ্ধৃতি দেওয়া সম্ভব নয়। অ্যারে ব্যবহারের পরিবর্তে একটি ফাংশন ব্যবহার করা যেতে পারে এবং স্ট্রিংফাইড করা যায়:

var actualCode = '(' + function() {
    // All code is executed in a local scope.
    // For example, the following does NOT overwrite the global `alert` method
    var alert = null;
    // To overwrite a global variable, prefix `window`:
    window.alert = null;
} + ')();';
var script = document.createElement('script');
script.textContent = actualCode;
(document.head||document.documentElement).appendChild(script);
script.remove();

এই পদ্ধতিটি কাজ করে, কারণ +স্ট্রিংগুলিতে অপারেটর এবং একটি ফাংশন সমস্ত বস্তুকে একটি স্ট্রিংয়ে রূপান্তর করে। যদি আপনি কোডটি একাধিকবার ব্যবহারের উদ্দেশ্যে থাকেন তবে কোড পুনরাবৃত্তি এড়াতে কোনও ফাংশন তৈরি করা বুদ্ধিমানের কাজ। একটি বাস্তবায়ন এর মত দেখতে পারে:

function injectScript(func) {
    var actualCode = '(' + func + ')();'
    ...
}
injectScript(function() {
   alert("Injected script");
});

দ্রষ্টব্য: ফাংশনটি ক্রমিকায়িত হওয়ার কারণে, আসল সুযোগ এবং সমস্ত সীমাবদ্ধ বৈশিষ্ট্যগুলি হারিয়ে গেছে!

var scriptToInject = function() {
    console.log(typeof scriptToInject);
};
injectScript(scriptToInject);
// Console output:  "undefined"

পদ্ধতি 3: একটি ইনলাইন ইভেন্ট ব্যবহার করা

কখনও কখনও আপনি কিছু কোড তত্ক্ষণাত চালাতে চান, যেমন <head>উপাদান তৈরির আগে কিছু কোড চালানো । এটি <script>দিয়ে একটি ট্যাগ প্রবেশ করিয়ে করা যায় textContent(পদ্ধতি 2/2 বি দেখুন)।

একটি বিকল্প, তবে প্রস্তাবিত নয় ইনলাইন ইভেন্টগুলি ব্যবহার করা use এটি প্রস্তাবিত নয় কারণ যদি পৃষ্ঠাটি কোনও সামগ্রী সুরক্ষা নীতি সংজ্ঞায়িত করে যা ইনলাইন স্ক্রিপ্টগুলি নিষিদ্ধ করে, তবে ইনলাইন ইভেন্ট শ্রোতাগুলিকে অবরুদ্ধ করা হবে। অন্যদিকে এক্সটেনশন দ্বারা ইনজেক্ট করা ইনলাইন স্ক্রিপ্টগুলি এখনও চলছে। আপনি যদি এখনও ইনলাইন ইভেন্টগুলি ব্যবহার করতে চান তবে এইভাবে:

var actualCode = '// Some code example \n' + 
                 'console.log(document.documentElement.outerHTML);';

document.documentElement.setAttribute('onreset', actualCode);
document.documentElement.dispatchEvent(new CustomEvent('reset'));
document.documentElement.removeAttribute('onreset');

দ্রষ্টব্য: এই পদ্ধতিটি ধরে নিয়েছে যে ইভেন্টটি পরিচালনা করে এমন কোনও বিশ্বব্যাপী ইভেন্ট শ্রোতা নেই reset। যদি থাকে তবে আপনি অন্যান্য বৈশ্বিক ইভেন্টগুলির মধ্যে একটি চয়ন করতে পারেন। কেবল জাভাস্ক্রিপ্ট কনসোল (F12) খুলুন, টাইপ document.documentElement.onকরুন এবং উপলভ্য ইভেন্টগুলির চয়ন করুন।

ইনজেকশন কোডটিতে গতিশীল মান

মাঝেমধ্যে, আপনাকে ইনজেকশন ফাংশনটিতে একটি স্বেচ্ছাসেবী পরিবর্তন করতে হবে pass উদাহরণ স্বরূপ:

var GREETING = "Hi, I'm ";
var NAME = "Rob";
var scriptToInject = function() {
    alert(GREETING + NAME);
};

এই কোডটি ইনজেক্ট করার জন্য, আপনাকে বেনামে ফাংশনে আর্গুমেন্ট হিসাবে ভেরিয়েবলগুলি পাস করতে হবে। এটি সঠিকভাবে প্রয়োগ করতে ভুলবেন না! নিম্নলিখিতগুলি কাজ করবে না :

var scriptToInject = function (GREETING, NAME) { ... };
var actualCode = '(' + scriptToInject + ')(' + GREETING + ',' + NAME + ')';
// The previous will work for numbers and booleans, but not strings.
// To see why, have a look at the resulting string:
var actualCode = "(function(GREETING, NAME) {...})(Hi, I'm ,Rob)";
//                                                 ^^^^^^^^ ^^^ No string literals!

JSON.stringifyযুক্তিটি পাস করার আগে সমাধানটি ব্যবহার করা হয় । উদাহরণ:

var actualCode = '(' + function(greeting, name) { ...
} + ')(' + JSON.stringify(GREETING) + ',' + JSON.stringify(NAME) + ')';

আপনার যদি অনেকগুলি ভেরিয়েবল থাকে তবে JSON.stringifyপড়ার যোগ্যতা উন্নত করতে একবারে এটি ব্যবহার করা সার্থক :

...
} + ')(' + JSON.stringify([arg1, arg2, arg3, arg4]) + ')';

81
এই উত্তরটি অফিসিয়াল ডক্সের অংশ হওয়া উচিত। সরকারী দস্তাবেজগুলি প্রস্তাবিত উপায়ে জাহাজে পাঠানো উচিত -> একই জিনিসটি করার 3 উপায় ... ভুল?
মার্স রবার্টসন

7
@ Qantas94 হ্যাভি এক্সটেনশনের সিএসপি সামগ্রী স্ক্রিপ্টগুলিকে প্রভাবিত করে না । কেবল পৃষ্ঠার সিএসপি প্রাসঙ্গিক। script-srcএক্সটেনশনের উত্স বাদ দেয় এমন নির্দেশিকা ব্যবহার করে পদ্ধতি 1 টি অবরুদ্ধ করা যেতে পারে , "অনিরাপদ-ইনলাইন" lud কে বাদ দিয়ে সিএসপি ব্যবহার করে পদ্ধতি 2 অবরুদ্ধ করা যেতে পারে `
রব ডব্লিউ

3
কেউ জিজ্ঞাসা করলেন আমি স্ক্রিপ্ট ট্যাগটি কেন ব্যবহার করে সরিয়ে ফেলছি script.parentNode.removeChild(script);। আমার এটি করার কারণটি কারণ আমি আমার জঞ্জাল পরিষ্কার করতে পছন্দ করি। নথিতে যখন কোনও ইনলাইন স্ক্রিপ্ট সন্নিবেশ করা হয় তখন তা অবিলম্বে কার্যকর করা হয় এবং <script>ট্যাগটি নিরাপদে সরিয়ে ফেলা যায়।
রব ডব্লু

9
অন্যান্য পদ্ধতি: location.href = "javascript: alert('yeah')";আপনার সামগ্রী স্ক্রিপ্টের যে কোনও জায়গায় ব্যবহার করুন। কোডের সংক্ষিপ্ত স্নিপেটের পক্ষে এটি আরও সহজ এবং পৃষ্ঠার জেএস বিষয়বস্তুগুলিতে অ্যাক্সেস করতে পারে।
মাটুল

3
@ ক্রিসিপ ব্যবহারে সতর্ক থাকুন javascript:। একাধিক লাইনে বিস্তৃত কোড প্রত্যাশার মতো কাজ করতে পারে না। ভারতের ব্যাটিং লাইন মন্তব্য ( //) বাকি অগ্রভাগ ছাঁটিয়া হবে, তাই এই ব্যর্থ হবে: location.href = 'javascript:// Do something <newline> alert(0);';। আপনি একাধিক-মন্তব্য মন্তব্য ব্যবহার করেছেন তা নিশ্চিত করে এটিকে উদ্বেগ দেওয়া যেতে পারে। আর একটি বিষয় সাবধান হওয়া উচিত হ'ল অভিব্যক্তির ফলাফলটি বাতিল হওয়া উচিত। javascript:window.x = 'some variable';দস্তাবেজটি আনলোড করতে এবং 'কিছু ভেরিয়েবল' বাক্যাংশের সাথে প্রতিস্থাপন করা হবে। যদি সঠিকভাবে ব্যবহার করা হয় তবে এটি প্রকৃতপক্ষে একটি আকর্ষণীয় বিকল্প <script>
রব ডব্লু

61

একমাত্র জিনিস অনুপস্থিত রব ডাব্লু এর দুর্দান্ত উত্তর থেকে লুকানো হ'ল ইনজেকশনযুক্ত পৃষ্ঠা স্ক্রিপ্ট এবং সামগ্রী স্ক্রিপ্টের মধ্যে কীভাবে যোগাযোগ করা যায়।

প্রাপ্তির দিকে (আপনার সামগ্রীর স্ক্রিপ্ট বা ইনজেকশন পৃষ্ঠা স্ক্রিপ্ট) ইভেন্ট শ্রোতাদের যুক্ত করুন:

document.addEventListener('yourCustomEvent', function (e) {
  var data = e.detail;
  console.log('received', data);
});

ইনিশিয়েটার দিকে (কন্টেন্ট স্ক্রিপ্ট বা ইনজেকশন পৃষ্ঠা স্ক্রিপ্ট) ইভেন্টটি প্রেরণ করুন:

var data = {
  allowedTypes: 'those supported by structured cloning, see the list below',
  inShort: 'no DOM elements or classes/functions',
};

document.dispatchEvent(new CustomEvent('yourCustomEvent', { detail: data }));

মন্তব্য:

  • ডিওএম মেসেজিং স্ট্রাকচার্ড ক্লোনিং অ্যালগরিদম ব্যবহার করে, যা কেবল স্থানান্তর করতে পারে আদিম মানগুলি ছাড়াও কিছু ধরণের ডেটা পারে। এটি শ্রেণীর উদাহরণ বা ফাংশন বা ডোম উপাদান পাঠাতে পারে না।
  • ফায়ারফক্সে, বিষয়বস্তু স্ক্রিপ্ট থেকে কোনও সামগ্রীর (যেমন কোনও প্রাথমিক মান নয়) প্রেক্ষাপটে পাঠানোর জন্য আপনাকে এটিকে স্পষ্ট করে লক্ষ্য cloneInto(একটি অন্তর্নির্মিত ফাংশন) ব্যবহার করে ক্লোন করতে হবে , অন্যথায় এটি সুরক্ষা লঙ্ঘনের ত্রুটির সাথে ব্যর্থ হবে'll ।

    document.dispatchEvent(new CustomEvent('yourCustomEvent', {
      detail: cloneInto(data, document.defaultView),
    }));

আমি আমার উত্তরের দ্বিতীয় লাইনে কোড এবং ব্যাখ্যাটির সাথে স্ট্যাকওভারফ্লো / প্রশ্নগুলি / 9602022/… সংযুক্ত করেছি
রব ডব্লু

1
আপনার আপডেট হওয়া পদ্ধতির (যেমন একটি বাগ রিপোর্ট বা একটি পরীক্ষার কেস?) জন্য কোনও রেফারেন্স রয়েছে কি? CustomEventকনস্ট্রাক্টর অবহেলিত document.createEventএপিআই ছাড়িয়ে দেয় ।
রব ডব্লু

আমার জন্য 'প্রেরণ অনুষ্ঠান (নতুন কাস্টমসেন্ট ...') কাজ করেছে I আমার ক্রোম 33 আছে Also এছাড়াও এটি আগে কাজ করেনি কারণ আমি জেএস কোডটি ইনজেকশনের পরে অ্যাডভেন্টলিস্টনার লিখেছিলাম
jscriPoint

আপনি কন্সট্রাক্টরের কাছে আপনার ২ য় পরামিতি হিসাবে যা পাস সে সম্পর্কে অতিরিক্ত সতর্কতা অবলম্বন করুন CustomEvent। আমি 2 টি খুব বিভ্রান্তিকর সমস্যায় পড়েছি: ১. ' nullকন্টেন্ট' এর স্ক্রিপ্টের শ্রোতা যখন পেয়েছেন তখন কেবল 'বিশদ' সম্পর্কে একক উক্তিটি বিস্মিত হয়ে মানটি তৈরি করে । ২. আরও গুরুত্বপূর্ণ বিষয়, কোনও কারণে আমার ছিল JSON.parse(JSON.stringify(myData))বা অন্যথায় এটিও হয়ে উঠবে null। এটি দেওয়া হলেও, আমার কাছে এটি প্রদর্শিত হবে যে নিম্নলিখিত ক্রোমিয়াম বিকাশকারীর দাবি - "কাঠামোগত ক্লোন" অ্যালগরিদম স্বয়ংক্রিয়ভাবে ব্যবহৃত হয় - এটি সত্য নয়। bugs.chromium.org/p/chromium/issues/detail?id=260378#c18
jdunk

আমি মনে করি সরকারী উপায়টি উইন্ডো.পোস্টমেসেজ: ডেভেলপার.চ্রোম.
এনরিক

9

আমি লোড হওয়া স্ক্রিপ্টগুলির ক্রমবিন্যাসের সমস্যার মুখোমুখি হয়েছি, যা স্ক্রিপ্টগুলির অনুক্রমিক লোডিংয়ের মাধ্যমে সমাধান করা হয়েছিল। লোডিং রব ডাব্লু এর উত্তর উপর ভিত্তি করে ।

function scriptFromFile(file) {
    var script = document.createElement("script");
    script.src = chrome.extension.getURL(file);
    return script;
}

function scriptFromSource(source) {
    var script = document.createElement("script");
    script.textContent = source;
    return script;
}

function inject(scripts) {
    if (scripts.length === 0)
        return;
    var otherScripts = scripts.slice(1);
    var script = scripts[0];
    var onload = function() {
        script.parentNode.removeChild(script);
        inject(otherScripts);
    };
    if (script.src != "") {
        script.onload = onload;
        document.head.appendChild(script);
    } else {
        document.head.appendChild(script);
        onload();
    }
}

ব্যবহারের উদাহরণটি হ'ল:

var formulaImageUrl = chrome.extension.getURL("formula.png");
var codeImageUrl = chrome.extension.getURL("code.png");

inject([
    scriptFromSource("var formulaImageUrl = '" + formulaImageUrl + "';"),
    scriptFromSource("var codeImageUrl = '" + codeImageUrl + "';"),
    scriptFromFile("EqEditor/eq_editor-lite-17.js"),
    scriptFromFile("EqEditor/eq_config.js"),
    scriptFromFile("highlight/highlight.pack.js"),
    scriptFromFile("injected.js")
]);

প্রকৃতপক্ষে, আমি জেএসের কাছে নতুন, তাই আমাকে আরও ভাল উপায়ে পিন করতে নির্দ্বিধায়।


3
স্ক্রিপ্টগুলি সন্নিবেশ করার এই উপায়টি ভাল নয়, কারণ আপনি ওয়েব পৃষ্ঠার নাম স্থান দূষিত করছেন। যদি ওয়েব পৃষ্ঠাটি নামক একটি ভেরিয়েবল ব্যবহার করে formulaImageUrlবা codeImageUrl, তবে আপনি কার্যকরভাবে পৃষ্ঠার কার্যকারিতাটি ধ্বংস করছেন। আপনি যদি ওয়েব পৃষ্ঠায় কোনও ভেরিয়েবল পাস করতে চান তবে আমি স্ক্রিপ্ট উপাদানটিতে ডেটা সংযুক্ত করার পরামর্শ দিচ্ছি ( e.g. script.dataset.formulaImageUrl = formulaImageUrl;) এবং (function() { var dataset = document.currentScript.dataset; alert(dataset.formulaImageUrl;) })();ডেটা অ্যাক্সেস করার জন্য স্ক্রিপ্টে যেমন ব্যবহার করুন।
রব ডব্লিউ

@ রব ডাব্লু আপনার নোটের জন্য আপনাকে ধন্যবাদ, যদিও এটি নমুনা সম্পর্কে আরও বেশি। আপনি কি দয়া করে স্পষ্ট করে বলতে পারেন, কেন আমি শুধু পাওয়ার পরিবর্তে আইআইএফই ব্যবহার করব dataset?
দিমিত্রি জিনজবার্গ

4
document.currentScriptএটি কার্যকর করার সময় কেবল স্ক্রিপ্ট ট্যাগকে নির্দেশ করে। আপনি যদি কখনও স্ক্রিপ্ট ট্যাগ এবং / অথবা এর বৈশিষ্ট্য / বৈশিষ্ট্যগুলি (যেমন dataset) অ্যাক্সেস করতে চান তবে আপনাকে এটি একটি ভেরিয়েবলে সংরক্ষণ করতে হবে। গ্লোবাল নেমস্পেসকে দূষিত না করে এই পরিবর্তনশীলটিকে সঞ্চয় করতে আমাদের কাছে একটি আইআইএফই দরকার।
রব ডব্লু

@ রবডাব্লু চমৎকার! তবে আমরা কেবল কিছু পরিবর্তনশীল নাম ব্যবহার করতে পারি না, যা বিদ্যমানটির সাথে খুব কমই ছেদ করতে পারে। এটি কি কেবল অ-পরিচয়মূলক নয় বা এটি নিয়ে আমাদের আরও কিছু সমস্যা হতে পারে?
দিমিত্রি জিনজবার্গ

2
আপনি পারতেন, কিন্তু আইআইএফই ব্যবহারের ব্যয়টি নগণ্য, সুতরাং আমি কোনও আইআইএফইয়ের চেয়ে নেমস্পেস দূষণকে প্রাধান্য দেওয়ার কারণ দেখছি না। আমি অবশ্যই মূল্যবান যে আমি অন্যের ওয়েবপৃষ্ঠাকে কোনওভাবে ভেঙে ফেলব না এবং সংক্ষিপ্ত পরিবর্তনশীল নামগুলি ব্যবহার করার ক্ষমতাও রাখব । আইআইএফই ব্যবহারের আরেকটি সুবিধা হ'ল আপনি চাইলে ( return;) চাইলে স্ক্রিপ্টটি প্রস্থান করতে পারেন ।
রব ডব্লু

6

সামগ্রী স্ক্রিপ্টে, আমি মাথায় স্ক্রিপ্ট ট্যাগ যুক্ত করি যা আমি ব্যবহার করি এমন হ্যান্ডলারের অভ্যন্তরে, একটি 'অনমেসেজ' হ্যান্ডলারের সাথে সংযুক্ত থাকে, কোড সম্পাদন করতে ইওয়াল। বুথ কনটেন্ট স্ক্রিপ্টে আমি onmessage হ্যান্ডলারটিও ব্যবহার করি, তাই আমি দ্বিপথে যোগাযোগ করি। ক্রোম ডক্স

//Content Script

var pmsgUrl = chrome.extension.getURL('pmListener.js');
$("head").first().append("<script src='"+pmsgUrl+"' type='text/javascript'></script>");


//Listening to messages from DOM
window.addEventListener("message", function(event) {
  console.log('CS :: message in from DOM', event);
  if(event.data.hasOwnProperty('cmdClient')) {
    var obj = JSON.parse(event.data.cmdClient);
    DoSomthingInContentScript(obj);
 }
});

pmListener.js একটি পোস্ট বার্তা ইউআরএল শ্রোতা

//pmListener.js

//Listen to messages from Content Script and Execute Them
window.addEventListener("message", function (msg) {
  console.log("im in REAL DOM");
  if (msg.data.cmnd) {
    eval(msg.data.cmnd);
  }
});

console.log("injected To Real Dom");

এইভাবে, আমি সিএস থেকে রিয়েল ডোমের মধ্যে 2 উপায় যোগাযোগ করতে পারি। এটির খুব উপকারী উদাহরণস্বরূপ, যদি আপনাকে ওয়েবসকেট ইভেন্টগুলি শুনতে বা মেমোরি ভেরিয়েবল বা ইভেন্টগুলির কোনও শুনতে হয়।


1

পৃষ্ঠার প্রসঙ্গে কোড চালানোর জন্য এবং প্রত্যাশিত মানটি ফিরে পাওয়ার উদ্দেশ্যে আপনি তৈরি করা একটি ইউটিলিটি ফাংশন ব্যবহার করতে পারেন।

এটি কোনও ফাংশনকে স্ট্রিংয়ে সিরিয়ালাইজ করে এবং এটি ওয়েব পৃষ্ঠায় ইনজেকশনের মাধ্যমে করা হয়।

ইউটিলিটি এখানে গিটহাবটিতে উপলব্ধ

ব্যবহারের উদাহরণ -



// Some code that exists only in the page context -
window.someProperty = 'property';
function someFunction(name = 'test') {
    return new Promise(res => setTimeout(()=>res('resolved ' + name), 1200));
}
/////////////////

// Content script examples -

await runInPageContext(() => someProperty); // returns 'property'

await runInPageContext(() => someFunction()); // returns 'resolved test'

await runInPageContext(async (name) => someFunction(name), 'with name' ); // 'resolved with name'

await runInPageContext(async (...args) => someFunction(...args), 'with spread operator and rest parameters' ); // returns 'resolved with spread operator and rest parameters'

await runInPageContext({
    func: (name) => someFunction(name),
    args: ['with params object'],
    doc: document,
    timeout: 10000
} ); // returns 'resolved with params object'


0

আপনি যদি পাঠ্যের পরিবর্তে খাঁটি ফাংশনটি ইনজেক্ট করতে চান তবে আপনি এই পদ্ধতিটি ব্যবহার করতে পারেন:

function inject(){
    document.body.style.backgroundColor = 'blue';
}

// this includes the function as text and the barentheses make it run itself.
var actualCode = "("+inject+")()"; 

document.documentElement.setAttribute('onreset', actualCode);
document.documentElement.dispatchEvent(new CustomEvent('reset'));
document.documentElement.removeAttribute('onreset');

এবং আপনি ফাংশনগুলিতে প্যারামিটারগুলি (দুর্ভাগ্যবশত কোনও অবজেক্ট এবং অ্যারেগুলি স্ট্রাইফাইং করা যায় না) পাস করতে পারেন। এটি বারেটিসে যুক্ত করুন, এর মতো:

function inject(color){
    document.body.style.backgroundColor = color;
}

// this includes the function as text and the barentheses make it run itself.
var color = 'yellow';
var actualCode = "("+inject+")("+color+")"; 


এটি বেশ দুর্দান্ত ... তবে রঙের জন্য একটি পরিবর্তনশীল সহ দ্বিতীয় সংস্করণটি আমার পক্ষে কাজ করে না ... আমি 'অচেনা' পেয়েছি এবং কোডটি একটি ত্রুটি ছুঁড়েছে ... এটি পরিবর্তনশীল হিসাবে দেখায় না।
11 ই
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.