javascript - 如何将文件传递给 PHP 并在一个脚本中将其下载回来?

标签 javascript php html

很抱歉,我很确定有一天我看到过类似的问题,但我找不到它,而且我自己也想不出来。

我需要能够在本地保存一个 JSON 文件,但是下载属性和文件 API 对浏览器不够友好,所以我决定将 JSON 字符串发送到服务器并让服务器将文件发送给我使浏览器下载它的正确 HTTP header 。

但是我不想离开这个页面。据我所知,AJAX 无法触发文件下载(或者我一直在尝试错误),因此我必须使用隐藏的 HTML 表单,通过 POST 发送数据。如何将 POST 数据发送到 php 文件,该文件将在不离开页面的情况下返回要下载的文件?

我在 AJAX 中尝试过的:

sd.requestDownload = function() {
  if(sd.request && 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 && (sd.request.status == 200 || sd.request.status == 0)) {
      // download?
    } else if(sd.request.readyState < 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()));
};

PHP代码:

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

最佳答案

我想出了一些可行的方法,但 IE 显示有关在调试器中缺少文档类型的错误。我的解决方案涉及在 JS 中创建一个表单,而不将其附加到页面。 如果 HTTP header 表明它是文件附件,则页面不会更改。我见过人们谈论将目标设置为 iframe 或“_blank”以获得额外的安全性,但 Chrome 认为此类调用是弹出窗口,因此它会阻止它们并且不会在用户单击“时再次发送 POST 请求”显示弹出窗口”。

编辑:如果表单不在页面上,IE 似乎会忽略对 submit() 的调用。因此我修改了代码。

这个问题给了我这个想法:JavaScript post request like a form submit

PHP

if(isset($_POST['filecontent'])) {
  header('Content-Type: application/octet-stream; charset=utf-8');
  if(isset($_POST['filename'])) {
    header('Content-Disposition: attachment; filename=' . preg_replace('/[^a-zA-Z0-9_\.]+/', "", $_POST['filename']));
  } else {
    header('Content-Disposition: attachment;');
  }
  $file = $_POST['filecontent'];
} 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 $file;

JS

download = function(filename, filecontent) {
  var form = document.createElement("form");
  form.setAttribute("method", "post");
  form.setAttribute("action", "save.php");
  form.style.display = "none";
  var i = document.createElement("input");
  i.setAttribute("type", "hidden");
  i.setAttribute("name", "filename");
  i.setAttribute("value", filename);
  form.appendChild(i);
  i = document.createElement("input");
  i.setAttribute("type", "hidden");
  i.setAttribute("name", "filecontent");
  i.setAttribute("value", filecontent);
  form.appendChild(i);

  document.body.appendChild(form);
  form.submit();
  document.body.removeChild(form);
};

关于javascript - 如何将文件传递给 PHP 并在一个脚本中将其下载回来?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29828986/

相关文章:

php - 从字符串创建数组

javascript - 为什么鼠标悬停时 Chart.js 的工具提示出现在错误的位置?

javascript - 输入标签,如何在事件中将数字重置为1

javascript - flowjs 0.54.0 中的新 "Missing annotation"错误

javascript - 想要使用 Ajax 更新数据库中每一行的下拉列表

php - 如何验证 php post 变量?

javascript - 如何在文本区域为空时删除元素?

javascript - 如何从 anchor child 获取父 div id

javascript - Javascript 中 IIFE 的作用域

javascript - 使 <a> 标签中的 href 属性具有反应性