在iframe中形成POST而不影响历史记录

时间:2009-10-20 21:53:35

标签: javascript ajax cross-domain browser-history

是否可以在iframe中提交表单而不影响浏览器的历史记录?

我已经实现了发送跨域POST请求。它使用Javascript在iframe中创建和提交表单。它有效,但每个请求都会在浏览器的历史记录中添加一个项目。

有人知道解决这个问题吗?我尝试用innerHTML和createElement创建iframe。到目前为止,我没有看到任何差异。

PS - 我很乐意使用XMLHtttpRequest(“Ajax”),但它不支持跨域发送数据。我希望使用GET而不是发布,但我需要发送超过2k的数据。

这是我的代码的一个版本。我已经尝试了很多变化并且已经搜索过了,但我似乎无法找到一个不影响浏览器历史的解决方案。我相信这是不可能的 - 任何人都可以确认吗?

<html>

<head>
  <script type="text/javascript">
    function submit(params) {

      var div = document.createElement('div');
      div.innerHTML = '<iframe height="50" width="50"></iframe>';
      document.body.appendChild(div);

      var iframe = div.firstChild;
      var iframeDocument = iframe.contentDocument || iframe.contentWindow.document;
      iframeDocument.open();
      iframeDocument.close();

      var form = iframeDocument.createElement('form');
      iframeDocument.body.appendChild(form);
      form.setAttribute('action', 'http://some-other-domain.com/submit-here');
      form.setAttribute('method', 'POST');

      for (param in params) {
        var field = iframeDocument.createElement('input');
        field.setAttribute('type', 'hidden');
        field.setAttribute('name', param);
        field.setAttribute('value', params[param]);
        form.appendChild(field);
      }
      form.submit();
    }

    window.onload = function() {
      document.getElementById('button').onclick = function() {
        submit({
          'x' : 'Some Value',
          'y' : 'Another Value',
          'z' : new Date().getTime()
        });
      }
    }
  </script>
</head>

<body>
  <h1>Example of using Javascript to POST across domains...</h1>
  <input id="button" type="button" value="click to send">
</body>

</html>

5 个答案:

答案 0 :(得分:3)

You should use an AJAX POST

  

Usually在创建Ajax应用程序时只使用GET方法。但是在创建ajax请求时,有几次需要POST。这可能有几个原因。例如,POST请求被认为比GET请求更安全,因为创建POST请求比创建GET请求相对困难。

AJAX调用未存储在浏览历史记录中。

答案 1 :(得分:1)

使用JS添加其src托管在您的站点(第三方托管脚本需要向其发送数据的域)的IFRAME是否有效?)此IFRAME可以包含所需的Javascript以使XMLHttpRequest成为你/它的域名。至于从第三方网站获取此IFRAME的实际数据 - 请尝试:http://softwareas.com/cross-domain-communication-with-iframes。这是一个非常聪明的解决方案,涉及在IFRAME URL的末尾更改片段标识符(#something),然后您可以通过IFRAME中的JS读取它。

另外一个猜测,但是如果你将this past SO solution发送到类似的历史问题(使用location.replace)上面,这有希望让你在不破坏历史堆栈的情况下进行锚定更改部分。

答案 2 :(得分:0)

如果您的服务器可以运行代码,您可以对服务器上的“代理”页面执行ajax查询,然后自己在远程服务器上运行请求并将结果返回到您的页面。

答案 3 :(得分:0)

(?)我没有看到你使用iframe元素的充分理由。 (因为这是一个较老的问题,也许你正在测试1997年的复古HTML 4.顺便说一句,忽略对象名称中的“XML” - 它是2000年及以后版本的[X] HTML的结转 - 没有XML必需的。)

如果您从JavaScript而不是文档中的元素发送HTTP请求,则不会向历史记录添加任何内容。

function httpPost(body) {
  req = new XMLHttpRequest();
  req.open("POST", "/submit-here", true/*async*/);
     // or "http://some-other-domain.com/submit-here"
  req.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
  req.send(body);
}
window.onload = function() {
   document.getElementById('button').onclick = function() {
      httpPost('x=Some+Value&y=Another+Value&z=' + new Date().getTime());
      // or use a buildQuery function, JQuery formSerialize, etc. to create the body
   }
}

我使用符号链接(“ln -s ...”),以便表单可以提交到与文档相同的域,因此在我的情况下,“/ submit-here”是相对URI。

答案 4 :(得分:-2)

如评论中所述,此问题的解决方案是从服务器发出AJAX请求,而不是尝试正常提交页面。 W3schools有一个非常好的AJAX介绍,你可以在这里找到:http://www.w3schools.com/Ajax/Default.Asp

基本上,AJAX使用javascript向服务器发送请求并显示响应,因为它使用Pure javascript发生,然后页面不会重新加载,历史记录根本不会受到影响。这听起来就像你想要的那样。

编辑: AJAX无法发布数据。

我其实认为它可以;或者至少有一些解决方法可以让你发布数据。见这里:

http://www.captain.at/howto-ajax-form-post-request.php

这似乎是以一种相当直接的方式做到的。请参阅页面底部的代码。具体做法是:

http_request.onreadystatechange = alertContents;
http_request.open('POST', url, true);
http_request.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
http_request.setRequestHeader("Content-length", parameters.length);
http_request.setRequestHeader("Connection", "close");
http_request.send(parameters);