2015-04-28 47 views
7

This question要求使用window.open打开新窗口,然后用脚本注入。由于跨域安全问题,这是不可能的。用脚本注入打开的窗口

但是,我的问题是,我想要做同样的事情,除了从同一个域到同一个域。这可能吗?

请注意,.write不能解决此问题,因为它先从页面中清除所有的html。

回答

8

你可以做这样的事情:

var theWindow = window.open('http://stackoverflow.com'), 
    theDoc = theWindow.document, 
    theScript = document.createElement('script'); 
function injectThis() { 
    // The code you want to inject goes here 
    alert(document.body.innerHTML); 
} 
theScript.innerHTML = 'window.onload = ' + injectThis.toString() + ';'; 
theDoc.body.appendChild(theScript); 

这也似乎工作:

var theWindow = window.open('http://stackoverflow.com'), 
    theScript = document.createElement('script'); 
function injectThis() { 
    // The code you want to inject goes here 
    alert(document.body.innerHTML); 
} 
// Self executing function 
theScript.innerHTML = '(' + injectThis.toString() + '());'; 
theWindow.onload = function() { 
    // Append the script to the new window's body. 
    // Only seems to work with `this` 
    this.document.body.appendChild(theScript); 
}; 

如果因为某些原因,你想使用eval:

var theWindow = window.open('http://stackoverflow.com'), 
    theScript; 
function injectThis() { 
    // The code you want to inject goes here 
    alert(document.body.innerHTML); 
} 
// Self executing function 
theScript = '(' + injectThis.toString() + '());'; 
theWindow.onload = function() { 
    this.eval(theScript); 
}; 

这样做什么(解释代码的第一位。所有的例子都相当类似):

  • 打开新窗口
  • 获取到新窗口的document
  • 创建脚本元素的引用
  • 将全部要“注入”到代码一个函数
  • 当加载窗口 时,使用window.onload事件(您也可以使用addEventListener)将脚本的innerHTML更改为加载所述函数。为方便起见,我使用了toString(),因此您不必串联一串字符串。 toString基本上将整个injectThis函数返回为一个字符串。
  • 将脚本追加到新窗口的document.body,它不会将其附加到加载的文档,它会在加载之前追加它(空的主体),这就是为什么您必须使用window.onload,所以您的脚本可以操纵新文档。

它可能使用window.addEventListener('load', injectThis.toString());,而不是window.onload一个好主意,如果你已经使用了window.onload事件新的页面中的脚本(它会覆盖注入脚本)。

注意,你可以做任何事情的injectThis函数中:追加资料核实,做DOM查询,添加更多的脚本等等...

还要注意的是,你可以操纵theWindow.onload内的新窗口中的DOM事件,使用this

+0

在IE11上不起作用。 – Suncatcher

+0

在FF上工作。铬?没有。 –

0

是...

var w = window.open(<your local url>); 
w.document.write('<html><head>...</head><body>...</body></html>'); 
+0

这会擦除网页,直到没有任何东西再注入。 – DaemonOfTheWest

+0

这是一个简单的例子。一旦拥有了文档对象,就可以像处理其他任何文档对象一样操作它。请记住,您需要等到DOM加载后才能开始操作。 –

+0

不,每当您使用'.write'时,都会首先清除目标中的所有内容。无所谓你在做什么 - 这是行不通的。 – DaemonOfTheWest

0

这里有一个窍门我使用,它使用查询字符串,并且是客户端。并不完美,但它的工作原理:

在发送页面,这样做:

var javascriptToSend = encodeURIComponent("alert('Hi!');"); 
window.open('mypage.html?javascript=' + javascriptToSend); 

替换mypage.html您的网页。现在在接收页面上,添加:

(location.href.match(/(?:javascript)=([^&]+)/)[1])&&eval(decodeURIComponent(location.href.match(/(?:javascript)=([^&]+)/)[1])); 

您将不得不做一些来回以确保它的工作。


如果你有PHP可以接收页面上使用此更可靠的解决方案:

eval(decodeURIComponent(<?=$_GET['javascript'] ?>)); 
+0

以及如何在空白窗口'window.open(“”)'完成此操作? – Suncatcher