2015-04-28 48 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