我正试图在一个新的选项卡中运行一个脚本。我使用的代码是:
$ = jQuery;
function openAndPush(url, id) {
var win = window.open('https://example.com' + 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);
}
考虑以下因素:
- 这个答案给了我灵感,但我使用了jQuery
- 我在检查器/控制台中从中的另一个页面运行此代码https://example.com(是的,实际的域不是example.com,但目标url相对于原始选项卡总是在同一个域中(,以避免CORS错误
- 当我运行函数(比如
openAndPush('/target', 1)
(,然后在另一个检查器(一个用于新窗口(中检查代码时,控制台消息Starting magic...
不会显示(我等待10秒甚至更长时间(。但是,新的DOM元素(我正在创建的这个脚本(显示在Elements选项卡中(并且,在第一个控制台/检查器中,我可以看到New script appended!
消息(
(在这两种情况下,jQuery
都存在,但没有占用$
标识符,这似乎是未定义的,所以我手动占用它(
我的结论是,我的脚本没有在新窗口中执行。
我错过了什么?如何确保代码正在执行?
不要在文档中嵌入脚本元素,而是这样做。
- 将要在另一个选项卡中运行的代码封装到一个函数中
- 将包装好的函数绑定到新选项卡的窗口
- 调用该函数
这是我在控制台中运行的代码,它对我有效,即打开了另一个选项卡并显示了警报。
function openAndPush(url, id) {
var win = window.open('https://www.google.com');
win.test = function () {
win.alert("Starting magic...");
}
win.test();
setTimeout(function () {
win.document.body.appendChild(element);
console.log('New script appended!')
}, 10000);
}
发现我的错误在于创建新脚本节点时引用的原始文档,而不是目标文档(即win.document
(。我需要的是更改代码以引用新文档并直接创建节点,而不是在点的中间使用jQuery。所以我把代码改成这样:
function openAndPush(url, id) {
var win = window.open('https://streeteasy.com' + 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);
}
有了这段代码,基本上发生了一些事情:JS代码正在新文档的上下文中被解析(并创建其节点(。旧的替代方案涉及原始控制台(因为原始文档被隐式引用(。
将脚本发送到另一个网页是不好的做法。你可以使用复杂的URL传递一些查询参数,并通过另一个网页的源代码进行处理,这要好得多:
function doMagicAtUrlByRegionId (url, regionId) {
window.open(`https://example.com${url}?view=map&magic=true®ion_id=${regionId}`);
}