10

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

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

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

PS - 我很想使用 XMLHtttpRequest(“Ajax”),但它不支持跨域发送数据。而且我很想使用 GET 而不是 post,但我需要发送超过 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>
4

5 回答 5

3

您应该 使用 AJAX POST

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

AJAX 调用不会存储到浏览历史记录中。

于 2009-10-20T22:06:17.740 回答
1

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

也是一个猜测,但是如果您将过去的 SO 解决方案用于类似的历史问题(使用 location.replace)到上面,这有望让您在不破坏历史堆栈的情况下进行锚点更改部分。

于 2009-10-21T03:03:10.630 回答
0

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

于 2009-10-21T00:02:58.637 回答
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。

于 2012-02-17T16:15:40.360 回答
-2

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

本质上,AJAX 使用 javascript 向服务器发送请求并显示响应,因为它使用纯 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);
于 2009-10-20T22:06:49.487 回答