title: How to pass a file to PHP and download it back in one script?
body: <p>I'm sorry, I'm pretty sure I've seen a similar question one day but I can't find it and I can't figure it out on my own.</p>
  
  <p>I need to be able to save a JSON file locally, but the download attribute and the File API aren't browser-friendly enough so I decided to send the JSON string to the server and have the server send me the file with the right HTTP headers to make the browser download it.</p>
  
  <p>But I don't want to leave the page. From what I can see, AJAX can't trigger file download (or I've been trying it wrong), so I'd have to use a hidden HTML form which would send the data through POST. How can I send POST data to a php file which will return a file to download without leaving the page? </p>
  
  <p>What I've tried in AJAX:</p>
  
  <pre><code>sd.requestDownload = function() {
    if(sd.request &amp;&amp; sd.request.readyState != 0) {
      return false; // there's already a request in progress
    }
  
    sd.request = sd.createRequest();
  
    sd.request.onreadystatechange = function() {
      if(sd.request.readyState == 4 &amp;&amp; (sd.request.status == 200 || sd.request.status == 0)) {
        // download?
      } else if(sd.request.readyState &lt; 4) {
        // show loading screen here
      }
    }
  
    sd.request.open("POST", "save.php", true);
    sd.request.setRequestHeader("Content-Type", "application/x-www-form-urlencoded");
    sd.request.send("json=" + encodeURIComponent(sd.saveToJSON()));
  };
  </code></pre>
  
  <p>The PHP code:</p>
  
  <pre><code>&lt;?PHP
  
  session_start();
  
  $file = '';
  
  if(isset($_POST['json'])) {
    header('Content-Type: application/json; charset=utf-8');
    header('Content-Disposition: attachment; filename=plan.json');
    $file = $_POST['json'];
  } else if(isset($_POST['file'])) {
    header('Content-Type: application/octet-stream; charset=utf-8');
    header('Content-Disposition: attachment; filename=plan');
    $file = $_POST['file'];
  } else {
    http_response_code(400);
    $file = '400 ERROR: NO FILE RECEIVED';
  }
  
  header('Expires: Sun, 01 Jan 2015 00:00:00 GMT');
  header('Cache-Control: no-store, no-cache, must-revalidate');
  header('Cache-Control: post-check=0, pre-check=0', FALSE);
  header('Pragma: no-cache');
  
  echo htmlentities($file);
  </code></pre>