Chrome Extension: Get Page Variables in Content Script

后端 未结 9 968
抹茶落季
抹茶落季 2020-11-27 03:44

Is there any way to retrieve a page\'s javascript variables from a Google Chrome Content Script?

9条回答
  •  臣服心动
    2020-11-27 04:35

    This is way late but I just had the same requirement & created a simple standalone class to make getting variable values (or calling functions on objects in the page) really really easy. I used pieces from other answers on this page, which were very useful.

    The way it works is to inject a script tag into the page which accesses the variable you want, then it creates a div to hold the serialised version of the value as innerText. It then reads & deserialises this value, deletes the div and script elements it injected, so the dom is back to exactly what it was before.

        var objNativeGetter = {
    
            divsToTidyup: [],
            DIVID: 'someUniqueDivId',
            _tidyUp: function () {
                console.log(['going to tidy up ', this.divsToTidyup]);
                var el;
                while(el = this.divsToTidyup.shift()) {
                    console.log('removing element with ID : ' + el.getAttribute('id'));
                    el.parentNode.removeChild(el);
                }
            },
    
            // create a div to hold the serialised version of what we want to get at
            _createTheDiv: function () {
                var div = document.createElement('div');
                div.setAttribute('id', this.DIVID);
                div.innerText = '';
                document.body.appendChild(div);
                this.divsToTidyup.push(div);
            },
    
            _getTheValue: function () {
                return JSON.parse(document.getElementById(this.DIVID).innerText);
            },
    
            // find the page variable from the stringified version of what you would normally use to look in the symbol table
            // eg. pbjs.adUnits would be sent as the string: 'pbjs.adUnits'
            _findTheVar: function (strIdentifier) {
                var script = document.createElement('script');
                script.setAttribute('id', 'scrUnique');
                script.textContent = "\nconsole.log(['going to stringify the data into a div...', JSON.stringify(" + strIdentifier + ")]);\ndocument.getElementById('" + this.DIVID + "').innerText = JSON.stringify(" + strIdentifier + ");\n";
                (document.head||document.documentElement).appendChild(script);
                this.divsToTidyup.push(script);
            },
    
            // this is the only call you need to make eg.:
            // var val = objNativeGetter.find('someObject.someValue');
            // sendResponse({theValueYouWant: val});
            find: function(strIdentifier) {
                this._createTheDiv();
                this._findTheVar(strIdentifier);
                var ret = this._getTheValue();
                this._tidyUp();
                return ret;
            }
        };
    

    You use it like this:

    chrome.runtime.onMessage.addListener(
        function(request, sender, sendResponse) {
    
            var objNativeGetter = {
            .... the object code, above
            }
    
            // do some validation, then carefully call objNativeGetter.find(...) with a known string (don't use any user generated or dynamic string - keep tight control over this)
            var val = objNativeGetter.find('somePageObj.someMethod()');
            sendResponse({theValueYouWant: val});
        }
    );
    

提交回复
热议问题