[英]XMLHttpRequest POST in iFrame on Page Load
所以我想在頁面加載時通過iFrame發送XMLHttpRequest POST請求。 通過iFrame發布的原因是不顯示引薦來源。
Javascript:
function load() {
var http = new XMLHttpRequest();
var url = "action url here";
var params = "name1=one&name2=two";
http.open("POST", url, true);
http.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=UTF-8");
http.send(params);
}
HTML:
<body onload="load();">
<iframe name="f1" src="about:blank" id="noreferer" width="0px" height="0px" style="border: 0px none;"> </iframe>
</body>
如何將請求附加到iFrame。 任何幫助,將不勝感激。
更新:
對於有人問我為什么添加並觸發load();
在HTML正文中,下面是通過innerHTML
連接到f1 iframe的無引薦發布請求代碼,該代碼在所有瀏覽器中均有效,因為src is 'about blank'
。 但不是XMLHttpRequest,並且不具有添加標頭的功能。
Javascript:
function load() {
var postdata = '<form id=NoReferrerPost method=POST action=\'action url here\'>' +
'<input type=hidden name=name1 value=one />' +
'<input type=hidden name=name2 value=two />' +
'</form>';
top.frames['f1'].document.body.innerHTML=postdata;
top.frames['f1'].document.getElementById('NoReferrerPost').submit();
}
因此,仍然需要一種將XMLHttpRequest附加到iframe f1中的方法,就像上面的代碼一樣。
這里是部分起作用的一些解決方案:
@fedeghe HERE的解決方案使用src="data:text/html
並且沒有引用網址meta標簽,可以在某些瀏覽器上使用 。
使用src="data:text/html,
可以做到,但是至少要注意腳本的編碼
<iframe src="data:text/html,<html><head><meta name=%22referrer%22 content=%22no-referrer%22/></head><body><script>(function(){var http = new XMLHttpRequest(), url = %22http://www.yourTargetDomain.com%22, params = %22name1=one%26name2=two%22; http.open(%22POST%22, url, true); http.setRequestHeader(%22Content-type%22, %22application/x-www-form-urlencoded; charset=UTF-8%22); http.send(params);})(); </script></body></html>"
width=0 height=0 style="display:none;"></iframe>
如果你真的需要在某些時候做,userORbrow事件驅動,你可以不喜歡以下(也代替名稱以ID為屬性iframe
標簽,但其實並不重要):
<script>
function load () {
var targetDomain = "http://www.yourTargetDomain.com",
params = "name1=one%26name2=two",
html = '<html><head><meta name="referrer" content="no-referrer"/></head><body><script>(function(){var http = new XMLHttpRequest(), url = "' + targetDomain + '", params = "' + params + '"; http.open("POST", url, true); http.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=UTF-8"); http.send(params);})(); <\/script><\/body><\/html>',
src = "data:text/html;charset=utf-8,"+ escape(html);
document.getElementById('f1').src= src;
}
</script>
<body onload="load();">
<iframe id="f1" src="about:blank" width="0px" height="0px" style="border: 0px none;"> </iframe>
</body>
...那時候,我建議您的功能可以輕松實現:首先創建iframe(關於:空白src,隱藏...一個),然后添加它,然后觸發發布,等待請求成功(也許也消耗掉它) ),最后從dom中移除iframe,類似於:
<script>
function postIt (p, url, cb) {
url = url || "http://www.targetdomain.org";
p = p || {};
cb && (p.cb = +new Date);
var params = (function (o) {
var s=[];
for (var j in o) {
o.hasOwnProperty(j) && s.push(j+'='+o[j]);
}
return s.join('%26');
})(p),
html = '<html><head><meta name="referrer" content="no-referrer"/></head><body><script>(function(){var http = new XMLHttpRequest(), url = "' + url + '", params = "' + params + '";http.onreadystatechange = function(){if (http.readyState == 4 && http.status == 200){window.parent.postMessage("posted", "*");}};http.open("POST", url, true); http.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=UTF-8"); http.send(params);})(); <\/script><\/body><\/html>',
src = "data:text/html;charset=utf-8,"+ escape(html),
iframe = document.createElement('iframe');
iframe.style.display= 'none';
iframe.height = iframe.width = '0px';
window.addEventListener('message', function (e) {
e.data == "posted" && document.body.removeChild(iframe);
}, false);
iframe.src = src;
document.body.appendChild(iframe);
}
</script>
<body onload="postIt({hello:'there'});">
<h1>Hello world</h1>
</body>
如果你只打算是不發送referer
,那么你可以使用提它referrer-policy
。 在網頁的html中,只需添加元信息( source ):
<meta name="referrer" content="no-referrer" />
只需創建一個需要的html並在本地提供它並在您的計算機上對其進行測試。
$ cat untitled.html
<!DOCTYPE html>
<head>
<meta name="referrer" content="no-referrer" />
</head>
<body>
<p> SOME CONTENT </p>
<script>
(function(){
var http = new XMLHttpRequest();
var url = "https://demo6945017.mockable.io/random/post"
http.open("POST", url, true);
http.setRequestHeader("Content-type", "application/x-www-form-urlencoded; charset=UTF-8");
http.send();
})();
</script>
</body>
$ python -m http.server
在對其進行測試時,您可以看到帶有或不帶有Referrer-policy的請求標頭。
(Without the meta info -> With referrer)
POST /random/post HTTP/1.1
Host: demo6945017.mockable.io
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:61.0) Gecko/20100101 Firefox/61.0
Referer: http://localhost:8000/untitled.html
Content-type: application/x-www-form-urlencoded; charset=UTF-8
Origin: http://localhost:8000
===================================
(With the meta info -> Without referrer)
POST /random/post HTTP/1.1
Host: demo6945017.mockable.io
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.13; rv:61.0) Gecko/20100101 Firefox/61.0
Content-type: application/x-www-form-urlencoded; charset=UTF-8
Origin: http://localhost:8000
(我刪除了很多常見的標頭,例如content-length
和cache-control
以進行重新編排)
但是請注意,原始數據仍在每個請求上發送,並且無法更改,它與瀏覽器的行為有關。 此外,瀏覽器支持僅限於Chrome和Firefox。
在<body>
或<iframe>
標記中使用onload
不會更改引薦來源網址,因為仍會從父窗口中觸發代碼。
您應該在iframe中觸發Ajax。 如上例所示,將代碼從父窗口放入iframe中:
frames[0].window.foo = function(){
console.log ("Look at me, executed inside an iframe!", window);
}
您必須遵守同源策略 ,但在這種情況下,由於要更改引薦來源,因此您將擁有相同的起源和引薦來源,因此引薦不會改變 。
同樣, 瀏覽器會在ajax請求中設置引薦來源網址 (請參見this和this ), 盡管事實上存在一個引薦來源標頭來操縱引薦來源行為 。 不幸的是,諸如<meta name="referrer" content="no-referrer" />
有一些重要的限制 (不支持Edge,IE和Safari)。
因此,我認為更改或隱藏引薦來源網址的一種可能方法是通過某種服務器代理。 這是:將所有ajax請求重定向到由您控制的一台服務器,在該服務器中執行POST / GET請求,在這種情況下,隱藏引薦來源網址。 實際上,這很簡單,這是一個使用php(CURL)和javascript的示例:
myproxy.php:
<?php
$url = $_GET['url'];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_REFERER, "referrer you want");//<-- spoof referrer here
$output = curl_exec($ch);
curl_close($ch);
echo $content;//content is from $_GET['url'] passed from javascript ajax
?>
在JavaScript中
var url = "Url we want to hide the referrer";
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
//response from myproxy.php here
}
};
xhttp.open("GET", "myproxy.php?="+url , true);
xhttp.send();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.