开发者

form POST in iframe without affecting history

Is it possible to submit a form inside an iframe without affecting the browser's history?

I've implemented sending a cross domain POST request. It uses Javascript to create and submit a form inside an iframe. It works, but each request adds an item to the browser's history.

Anyone know a w开发者_运维百科ay around this? I've tried creating the iframe with both innerHTML and createElement. I've seen no difference so far.

PS - I would love to use XMLHtttpRequest ("Ajax"), but it doesn't support sending data across domains. And I would love to use GET instead of post, but I need to send more than 2k of data.

Here's one version of my code. I've tried many variations and have searched all over, butI can't seem to find a solution that doesn't affect the browser's history. I believe it's not possible -- can anyone confirm that?

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


You should use an AJAX POST.

Usually only the GET method is used while creating Ajax apps. But there are several occasions when POST is necessary when creating a ajax request. This could be for several reasons. For example, POST request are considered more secure than GET request as creating a POST request is relatively harder than creating a GET request.

AJAX calls aren't stored into the browsing history.


Does it work to use JS to add an IFRAME whose src is hosted at your site (the domain to which the third-party-hosted script needs to send data?) This IFRAME could include the needed Javascript to make an XMLHttpRequest to your/its domain. And as for getting the actual data to this IFRAME from the third-party-site - try: http://softwareas.com/cross-domain-communication-with-iframes . It's a pretty clever solution involving changing fragment identifiers (#something) at the end of the IFRAME URL, which you can then read via JS within the IFRAME.

Also a guess, but if you tack this past SO solution to a similar history problem (using location.replace) on to the above this hopefully should let you do the anchor-changing part without disrupting the history stack.


If your server can run code, you could probably do an ajax query to a "proxy" page on your server, that would then itself run the request on the remote server and return the results to your page.


(?) I don't see a good reason that you are using an iframe element. (Since this was an older question, maybe you were testing in 1997-vintage HTML 4. BTW, ignore the "XML" in the object name - it's a carry over from the year 2000 and later versions of [X]HTML - no XML required.)

If you send the HTTP request from JavaScript rather than from elements in the document, nothing will be added to the history.

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
   }
}

I use symbolic links ("ln -s ...") so that the forms can be submitted to the same domain as the document, so in my case the "/submit-here" is a relative URI.


As made in the comments, the solution to this problem is in making an AJAX request from your server instead of trying to submit the page normally. W3schools has a really good introduction to AJAX that you can find here: http://www.w3schools.com/Ajax/Default.Asp

Essentially, AJAX uses javascript to send a request to the server and displays the response and because it happens using Pure javascript then the page does not reload and history is not affected at all. Which sounds like exactly what you want.

Edit: AJAX can not post data.

I actually think it can; or at least there are some workarounds that let you post data. See here:

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

That seems to do it in a rather straightforward manner. See the code at the bottom of the page. Specifically:

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);
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜