简体   繁体   English

页面加载在iFrame中的XMLHttpRequest POST

[英]XMLHttpRequest POST in iFrame on Page Load

So i want to send a XMLHttpRequest POST request through an iFrame on page load. 所以我想在页面加载时通过iFrame发送XMLHttpRequest POST请求。 Reason for posting via an iFrame is to not show referrer. 通过iFrame发布的原因是不显示引荐来源。

Javascript: 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: HTML:

<body onload="load();">
<iframe name="f1" src="about:blank" id="noreferer" width="0px" height="0px" style="border: 0px none;"> </iframe>
</body>

How can i attach the Request to the iFrame. 如何将请求附加到iFrame。 Any help would be appreciated. 任何帮助,将不胜感激。



UPDATE: 更新:

For anyone asking why i added and fired load(); 对于有人问我为什么添加并触发load(); in the HTML body, Below is a no referrer post request code connected to the f1 iframe via innerHTML that works in all browsers because the src is 'about blank' . 在HTML正文中,下面是通过innerHTML连接到f1 iframe的无引荐发布请求代码,该代码在所有浏览器中均有效,因为src is 'about blank' But not a XMLHttpRequest and doesn't give ability to add headers. 但不是XMLHttpRequest,并且不具有添加标头的功能。

Javascript: 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();
}

So what is still needed is a way to attach a XMLHttpRequest to post in iframe f1 like my code above. 因此,仍然需要一种将XMLHttpRequest附加到iframe f1中的方法,就像上面的代码一样。


HERE ARE SOME SOLUTIONS THAT PARTIALLY WORKS: 这里是部分起作用的一些解决方案:

The solution of @fedeghe HERE using src="data:text/html with no-referrer meta tag, could work on some browsers . @fedeghe HERE的解决方案使用src="data:text/html并且没有引用网址meta标签,可以在某些浏览器上使用

Using the src="data:text/html, , you can do it but you have to take care at least about the encoding of the script 使用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>

You can read more details about it here and here 您可以在这里这里阅读有关它的更多详细信息

UPDATE onload 更新加载

in case you really need to do it at some point, userORbrow event driven you could do something like the following (replaced also the name attribute with id for the iframe tag, but doesn't really matter): 如果你真的需要在某些时候做,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>

...at that point I suggest that Your function could easily: first create the iframe (about:blank src, hidden ...an on), second append it, then trigger the post, wait for request success (maybe also consume it), and remove finally the iframe from the dom, something similar to: ...那时候,我建议您的功能可以轻松实现:首先创建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>

If you're only intent is to not send the referer , then you can mention it using the referrer-policy . 如果你只打算是不发送referer ,那么你可以使用提它referrer-policy In the html of your webpage just add the meta information ( source ): 在网页的html中,只需添加元信息( source ):

<meta name="referrer" content="no-referrer" />

Just create a the requeired html and serve it locally and test it on your machine. 只需创建一个需要的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

On testing it, you can see the request headers with and without the referrer-policy. 在对其进行测试时,您可以看到带有或不带有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

(I've removed a lot of the common headers like content-length and cache-control for redablilty) (我删除了很多常见的标头,例如content-lengthcache-control以进行重新编排)
But beware that the origin is still being sent on every request and that cannot be changed, it tied to the behaviour of the browser. 但是请注意,原始数据仍在每个请求上发送,并且无法更改,它与浏览器的行为有关。 Also browser support is limited to Chrome and Firefox. 此外,浏览器支持仅限于Chrome和Firefox。

Using onload in <body> or in <iframe> tag doesn't change the referrer because the code is still fired from the parent window. <body><iframe>标记中使用onload不会更改引荐来源网址,因为仍会从父窗口中触发代码。

You should fire the ajax within the iframe. 您应该在iframe中触发Ajax。 To put code in the iframe from a parent window like this example : 如上例所示,将代码从父窗口放入iframe中:

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

you have to observe Same-origin policy , but in this case, since you want to change referrer, you will have the same origin and referrer, then referrer is not going to change . 您必须遵守同源策略 ,但在这种情况下,由于要更改引荐来源,因此您将拥有相同的起源和引荐来源,因此引荐不会改变

Also, browsers set the referrer in ajax requests (see this and this ) despite of the fact that exists a referrer header to manipulate the referrer behavior . 同样, 浏览器会在ajax请求中设置引荐来源网址 (请参见thisthis ), 尽管事实上存在一个引荐来源标头来操纵引荐来源行为 Somethig like <meta name="referrer" content="no-referrer" /> unfortunately has some important restrictions (no Edge, IE and Safari support). 不幸的是,诸如<meta name="referrer" content="no-referrer" />有一些重要的限制 (不支持Edge,IE和Safari)。

So I think a possible way to change or hide referrer is through some kind of server proxy. 因此,我认为更改或隐藏引荐来源网址的一种可能方法是通过某种服务器代理。 This is: redirecting all ajax requests to one server controlled by you, in the server you perform a POST/GET request and in this case hiding the referrer. 这是:将所有ajax请求重定向到由您控制的一台服务器,在该服务器中执行POST / GET请求,在这种情况下,隐藏引荐来源网址。 It's really simply in fact, here an example using php (CURL) and javascript: 实际上,这很简单,这是一个使用php(CURL)和javascript的示例:

myproxy.php: 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
?>

in javascript 在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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM