I am trying to run a script in a new tab. The code I use is this:
$ = jQuery;
function openAndPush(url, id) {
var win = window.open('' + url + '?view=map');
var element = $('<script type="text/javascript">console.log("Starting magic...");var region_id='+id+';$=jQuery;var p=$(\'div["se:map:paths"]\').attr(\'se:map:paths\');if(p){console.log("Found! pushing..."); $.get(\'https://localhost:9443/addPolygon\', {id: region_id, polygon: p}, function(){console.log("Done!")})}else{console.log("Not found!");}</script>').get(0);
setTimeout(function(){ win.document.body.appendChild(element);
console.log('New script appended!') }, 10000);
}
Considering the following:
- I was inspired in this answer, but used jQuery instead.
- I run this code in an inspector/console, from another page in (yes, the actual domain is not example - but the target url is always in the same domain with respect to the original tab) to avoid CORS errors.
- When I run the function (say,
openAndPush('/target', 1)
) and then inspect the code in another inspector, one for the new window, the console messageStarting magic...
is not shown (I wait the 10 seconds and perhaps more). However the new DOM element (this script I am creating) is shown in the Elements tab (and, in the first console/inspector, I can see theNew script appended!
message).
(In both cases jQuery
is present, but not occupying the $
identifier, which seems to be undefined - so I manually occupy it)
What I conclude is that my script is not being executed in the new window.
What am I missing? How can I ensure the code is being executed?
I am trying to run a script in a new tab. The code I use is this:
$ = jQuery;
function openAndPush(url, id) {
var win = window.open('https://example.' + url + '?view=map');
var element = $('<script type="text/javascript">console.log("Starting magic...");var region_id='+id+';$=jQuery;var p=$(\'div["se:map:paths"]\').attr(\'se:map:paths\');if(p){console.log("Found! pushing..."); $.get(\'https://localhost:9443/addPolygon\', {id: region_id, polygon: p}, function(){console.log("Done!")})}else{console.log("Not found!");}</script>').get(0);
setTimeout(function(){ win.document.body.appendChild(element);
console.log('New script appended!') }, 10000);
}
Considering the following:
- I was inspired in this answer, but used jQuery instead.
- I run this code in an inspector/console, from another page in https://example. (yes, the actual domain is not example. - but the target url is always in the same domain with respect to the original tab) to avoid CORS errors.
- When I run the function (say,
openAndPush('/target', 1)
) and then inspect the code in another inspector, one for the new window, the console messageStarting magic...
is not shown (I wait the 10 seconds and perhaps more). However the new DOM element (this script I am creating) is shown in the Elements tab (and, in the first console/inspector, I can see theNew script appended!
message).
(In both cases jQuery
is present, but not occupying the $
identifier, which seems to be undefined - so I manually occupy it)
What I conclude is that my script is not being executed in the new window.
What am I missing? How can I ensure the code is being executed?
Share Improve this question edited Jul 12, 2018 at 16:53 Luis Masuelli asked Jul 12, 2018 at 16:36 Luis MasuelliLuis Masuelli 12.3k11 gold badges52 silver badges88 bronze badges 3-
I'm confused on your second point. Do you mean that you are running a script on domain
aaa.
that opens a window tobbb.
and then adds a<script>
? – zero298 Commented Jul 12, 2018 at 16:41 - No. The domain is always the same. I just changed it to example – Luis Masuelli Commented Jul 12, 2018 at 16:44
- 1 This answer stackoverflow./questions/1199676/… seems to indicate that you can't do it the way you show, but must build and append a node. I seem to recall that scripts are not evaluated when injected as html, perhaps because the DOM is not reloaded and doesn't load and parse the script... no onLoad event fires to pick it up... or so I recall. – J E Carter II Commented Jul 12, 2018 at 16:55
3 Answers
Reset to default 13Instead of embedding script element in the document, do this.
- wrap the code that you want to run in another tab, into a function.
- bind that wrapped function to the new tab's window
- Call that function
Here's the code that I ran in my console and it worked for me i.e another tab was opened and alert was displayed.
function openAndPush(url, id) {
var win = window.open('https://www.google.');
win.test = function () {
win.alert("Starting magic...");
}
win.test();
setTimeout(function () {
win.document.body.appendChild(element);
console.log('New script appended!')
}, 10000);
}
Found that my error consisted on the origin document being referenced when creating a new script node, instead of the target document (i.e. win.document
). What I needed is to change the code to reference the new document and create the node directly, no jQuery in the middle at that point. So I changed my code like this:
function openAndPush(url, id) {
var win = window.open('https://streeteasy.' + url + '?view=map');
var element = win.document.createElement('script');
element.type='text/javascript';
element.innerHTML = 'console.log("Starting magic...");var region_id='+id+';$=jQuery;var p=$(\'div[se\\\\:map\\\\:paths]\').attr(\'se:map:paths\');if(p){console.log("Found! pushing..."); $.get(\'https://localhost:9443/addPolygon\', {id: region_id, polygon: p}, function(){console.log("Done!")})}else{console.log("Not found! searched in: ", document);}'
setTimeout(function(){ win.document.body.appendChild(element); console.log('New script appended!') }, 10000);
}
With this code something is essentially happening: The JS code is being parsed (and its node created) in the context of the new document. Older alternatives involved the origin console (since the origin document was implicitly referenced).
It's bad practice to send scripts to another webpage. You can pass some query params using a plicated URL and handle it by a source code from another webpage, it's much better:
function doMagicAtUrlByRegionId (url, regionId) {
window.open(`https://example.${url}?view=map&magic=true®ion_id=${regionId}`);
}