我有一个很大的系统 I need to generate a PDF file. I'd like to access it via REST API ,当然还有本地存储文件 .

文件内容取决于许多参数,该文件的内容应该是什么,即时间:从 - 到,过滤器,排序和许多,更多的参数;它们形成一个完全适合POST参数的JSON对象 . 参数不能通过GET,因为它们太大了 .

有一个FileSaver库在现代浏览器上完美运行 . 我创建了一个online demo . 但是当我下载旧浏览器 - firefox11,firefox12,firefox15时,它根本不起作用,即使我包含了Blob.js polyfill - 它打开了一个新的标签,其中包含以下网址: blob:457-343457-34574567-4576456 无法保存 . I need to support many browsers, not only the new ones.

The question is - I've got JSON parameters object inside my SPA app - how should I design this PDF binary file download

我想到了3种方法:

  • 强制浏览器在localhost上创建文件 - 使用FileSaver . WOrk适用于现代浏览器,不适用于旧版本

  • 创建可下载链接 . 我向REST API发送一个POST,包含所有参数,REST API返回如下内容: {"download": "mysite.com/download/ms2h5d34h53m"} ,响应用于显示指向用户的链接;用户可能会单击该链接(没有AJAX),服务器端API应该像过去那样返回一个文件 .

  • 不是我的,但在某处,我读到了我可以创建一个不可见的形式,向服务器发射POST,从而触发文件下载(这可能会减少返回 {"download": "mysite.com/download/ms2h5d34h53m"} JSON的步骤)

我需要有关如何做到这一点的指导 .


我试着在下面创建一个测试express.js服务器 . 当我直接访问 http://localhost:8081/download 时,我看到本地下载的PDF文件 . 但是当我尝试通过ajax / js访问它时:

enter image description here

然后内容被提取为二进制流:

enter image description here

var fs = require('fs');
var express = require('express');
var app = express();

app.get('/', function (req, res) {
  res.send('Hello World');
});

app.get('/download', function(req, res){
  var file = fs.readFileSync(__dirname + '/example.pdf', 'binary');
  res.setHeader('Content-Type', 'application/pdf');
  res.setHeader('Content-Length', file.length);
  res.setHeader('Content-Disposition', 'attachment; filename=new-name.pdf');
  res.setHeader('filename', 'sample.pdf');

  res.write(file, 'binary');
  res.end();
});

var server = app.listen(8081, function () {
  var host = server.address().address;
  var port = server.address().port;
  console.log("Example app listening at http://%s:%s", host, port);
});