页面加载中的iFrame中的XMLHttpRequest POST

时间:2017-11-21 13:10:51

标签: javascript html xmlhttprequest

所以我想在页面加载时通过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。任何帮助,将不胜感激。



更新:

如果有人问我为什么在HTML正文中添加并解雇了load();,则以下是通过innerHTML连接到f1 iframe的无推介者帖子请求代码,该代码适用于所有浏览器,因为{{1 }}。但不是XMLHttpRequest,也没有提供添加标题的能力。

使用Javascript:

src is 'about blank'

所以还需要一种方法来附加XMLHttpRequest以在iframe f1中发布,就像上面的代码一样。


以下是部分工作的解决方案:

@fedeghe HERE使用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(); } 和no-referrer元标记的解决方案可以在some browsers上使用。

3 个答案:

答案 0 :(得分:2)

使用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>

您可以阅读有关它的更多详细信息 herehere

更新加载

万一您确实需要执行此操作,可以通过userORbrow事件驱动执行以下操作(将 name 属性替换为{em> id {1}}标签,但并不重要)

iframe

...在这一点上,我建议您的功能可以轻松实现:首先创建iframe(关于:blank src,隐藏...一个),然后附加它,然后触发该帖子,等待请求成功(也许也将其消耗掉),最后从dom中移除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>

答案 1 :(得分:2)

如果您仅打算不发送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-lengthcache-control以便重新编排)
但是请注意,原始数据仍在每个请求上发送,并且无法更改,它与浏览器的行为有关。此外,浏览器支持仅限于Chrome和Firefox。

答案 2 :(得分:1)

onload<body>标记中使用<iframe>不会更改引荐来源网址,因为代码仍从父窗口中触发。

您应该在iframe中触发Ajax。要从this example之类的父窗口将代码放入iframe,请执行以下操作:

frames[0].window.foo = function(){
   console.log ("Look at me, executed inside an iframe!", window);
}

您必须遵守Same-origin policy,但在这种情况下,由于您想更改引荐来源,您将拥有相同的来源和引荐来源,因此引荐不会改变

此外,浏览器会在ajax请求中设置引荐来源网址(请参见thisthis尽管存在referrer header可以操纵的事实引荐来源行为。不幸的是,像<meta name="referrer" content="no-referrer" />这样的东西有一些重要的restrictions(不支持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();