我的场景
我有一个用MEEN堆栈编写的应用程序(MySQL,ExpressJS,EmberJS,NodeJS)。在一页中,我有一个表单输入。我应该获取输入数据,将其发送到服务器,生成PDF并在EmberJS中显示。服务器在NodeJS中使用ExpressJS,生成的文件在发送到前端之前被写入磁盘。
My problem:
我无法在EmberJS中显示PDF文件。或者更确切地说,什么都不显示。在我使用NodeJS和ExpressJS的后端中,我将PDF文件的文件组发送回EmberJS。使用像Chrome中的Postman扩展这样的REST客户端,就可以调用这个对话框,我可以保存这个文件。然而,在EmberJS中,没有出现对话框,但是我可以在Chrome中看到使用console.log
的文件内容。
为什么是这样?
下面是我在NodeJS中用ExpressJS发送文件的代码。
generatePDF: function(req, res){
var details = req.body;
// @param details
// @return relative path to the file
inventoryController.generatePDF(details, function(relPath){
var filePath = path.resolve(relPath);
// This is the first method
// I explicitly specify the header for the Response Object
// and pipe the ReadableStream to the Response Object
// var name = path.basename(filePath);
// var mimeType = mime.lookup(filePath);
// res.setHeader('Content-disposition', 'attachment; filename=' + name);
// res.setHeader('Content-type', mimeType);
// var fileStream = fs.createReadStream(filePath);
// fileStream.pipe(res);
// This is the second method (currently being used)
// using sendfile() of ExpressJS, the header is automatically set
res.sendfile(filePath);
});
},
Ember.js中用于向服务器发送详细信息和获取数据的代码。
var doc = {
// some attributes inside here
};
var url='/pdf';
var request = Ember.$.post(url, doc);
request.then(function(data){
if(data.status === 'ERR'){
// handling error
} else {
console.log('Successfully generated PDF.');
console.log(data); // I can see the filestream here
}
});
发布于 2014-07-02 13:29:39
我认为问题在于,这不是Ember.js问题,而是服务器问题,以及如何处理。jQuery无法将文件保存到磁盘,因为这是一种安全风险。虽然扩展可以覆盖各种安全限制,但在Ember或任何其他JavaScript框架(使用jQuery)中,您不能强制保存为对话框,因为这是由安全性强制执行的。JavaScript不能写入本地文件格式(除了在许多方面与cookies相似的html 5本地存储之外)。
因此,不能将保存保存为PDF。也许让它工作的唯一方法是允许浏览器自己捕获流并处理它:
您可以尝试这个插件,但我不确定它是否有效,根本不推荐它。
我建议您只使用浏览器中的纯链接,让服务器以正确的方式发送文件,而不是ajax调用。您可以让表单提交它,也可以使用查询字符串参数的纯链接。
客户端:
<a href="/server/getFile?{"contentID"="123", "user" = "test@me"}>Get File</a>
或
<form action="/getFile" method="POST">
<input type="hidden" id="user" name="user" value="test@me" />
<input type="hidden" id="contentID" name="contentID" value="123" />
<input type="submit" value="Get File />
</form>
服务器端:
在服务器中添加以下标题:
res.setHeader('Content-disposition', 'attachment; filename=<file name.ext>');
添加一个mime类型可能是一个明智的主意:
res.setHeader('Content-type', '<type>/<subtype>');
完整代码:
var filename = path.basename(filePath);
res.setHeader('Content-disposition', 'attachment; filename='+ filename);
res.setHeader('Content-type', 'application/pdf');
// it's better to use a stream than read all the file into memory.
var filestream = fs.createReadStream(filePath);
filestream.pipe(res);
或者,如果您使用的是快递,您可以使用这个辅助对象
res.download(filePath)
https://stackoverflow.com/questions/24505610
复制相似问题