在非ajax帖子中包含json数据

时间:2017-01-19 12:48:21

标签: javascript ajax

我有一个JavaScript Pivot表,可以向用户显示数据。用户可以选择列/行等。我已经添加了导出到Excel按钮,该按钮使用数据透视表的当前数据/视图(json数据)执行ajax发布。它将数据发布到我的服务器,将其转换为Excel文件。

创建文件一切正常,但我的问题是将文件传递给用户。根据我的阅读,我无法在ajax帖子后向用户发送文件。

我很高兴使用普通的html帖子(实际上它是我想要的,因为我可以将用户重定向到文件),但我不知道如何将数据透视表数据作为帖子的一部分包含在内因为它不是一种形式。

我知道我可以在本地保存文件并发回一个网址,但这会让事情变得复杂,我想避免它。

是否可以在不在本地保存文件并在文件所在位置发送URL的情况下执行此操作?

1 个答案:

答案 0 :(得分:1)

浏览器(尚未)支持表单的JSON序列化,因此AFAIK不可能使用纯表单将JSON发送到后端。

我有两个解决方案,不需要在服务器上保存文件:

1)简单的解决方案是使用JavaScript生成一个不可见的表单,创建名为json的隐藏输入,并用JSON内容填充它以发送到服务器。在服务器端,您将读取表单数据并解析存储在数据中的JSON。然后,您只需生成文件并发送文件作为响应。浏览器应该触发下载对话框。

var form = document.createElement('form');
form.method = 'post';
form.action = 'url';
var input = document.createElement('input');
input.type = 'hidden';
textarea.name = 'json';
textarea.value = JSON.stringify(your_json);
form.appendChild(input);
document.body.appendChild(form);
form.submit();
form.parentNode.removeChild(form);

2)第二个选项使用ajax将数据发送到服务器。但浏览器需要支持多个API。

您照常执行JSON请求,服务器应使用标头Content-Type: here-the-MIME-type-of-your-file和响应正文中的文件内容进行响应。

客户端的代码应如下所示:

var json = JSON.stringify({here: ['your', 'json', 'to', 'send', 'to', 'server']});
var xhr = new XMLHttpRequest();
xhr.open('POST', '/your/api/url', true);
xhr.setRequestHeader('Content-type', 'application/json');
xhr.responseType = 'arraybuffer';
xhr.addEventListener('load', function () {
  var blob = new Blob([this.response], { // reading response, not responseText
    type: this.getResponseHeader('Content-Type')
  });

  var url = URL.createObjectURL(blob);
  var a = document.createElement('a');
  a.href = url;
  a.download = 'file_name.txt'; // set proper extension
  document.body.appendChild(a); // it needs to be added to the document in order to work
  a.click();
  a.parentNode.removeChild(a);
});

xhr.send(json);

此外,创建的URL对象应该在某个时候撤销,否则它们将一直存在,直到页面重新加载。但我认为在用户下载文件之前不能撤销它们。所以这仍然是上述代码的一项任务。