angularjs - Res.download() 传递数据而不是下载文件
问题描述
我正在尝试将我的 NodeJS 服务器生成的文件作为可下载文件从服务器传递到客户端。
我的用户正在填写对象数据,然后将其存储在数据库中,创建文件的函数将读取对象以在生成的文件中填写数据。该文件包含十六进制数据(如果这很重要)。现在用户将选择他想要的对象,这会将它们分组到一个对象数组中,单击前端的按钮后,一个 POST 请求将数组发送到后端以生成文件(这是有效的) ,生成文件后,我检查以确保文件存在(确实存在),然后尝试使用 res.download('filepath/filename', 'downloadedname') 将其发送回前端(这不导致文件下载,但确实发送了一个 res,我认为这是 res.data 中文件的预期内容
完整的代码流程: AngularJS 控制器:
function DialogController($scope, $mdDialog, DashFactory, recipeBookService) {
$scope.recipes = [];
$scope.book = recipeBookService.getBook();
for(i=0; i<$scope.book.length; i++){
DashFactory.getRecipe($scope.book[i], function(data){
$scope.recipes.push(data);
});
}
$scope.empty = function(book) {
$scope.book = recipeBookService.clearBook();
$mdDialog.cancel();
};
$scope.generate = function(recipes){
DashFactory.generateFile(recipes)
}
$scope.delete = function(index){
$scope.recipes.splice(index, 1);
};
}
AngularJS 工厂:
factory.generateFile = function(recipes, callback){
console.log('factory recieved recipes', recipes);
$http({
url: '/createFile',
method: 'POST',
data: recipes
}).then(function(res){
console.log('success', res);
},function(res){
console.log('err', res);
})
}
节点服务器(相关部分)
const fs = require('fs');
createFile: function(req,res){
console.log('server reciped recipes', req.body);
if (createRecipeFile.writeRecipe(req.body)){
fs.access('server/generatedFiles/RecipeTest.REL', fs.constants.R_OK, (err) => {
console.log(`${'server/generatedFiles/RecipeTest.REL'} ${err ? 'is not readable' : 'is readable'}`);
res.download('server/generatedFiles/RecipeTest.REL', "G4R12.REL")
});
} else {
console.log('file creation failed');
res.sendStatus(500);
}
}
预期的结果是文件 server/generatedFiles/RecipeTest.REL 被下载为 G4R12.REL,当前结果是 chrome 记录的 res 如下:
{data: "↵&2B����LX����…
������������������������������{g]U", status:
200, headers: ƒ, config: {…}, statusText: "OK", …}
config:
data: Array(2)
0: {_id: "5be60e3d8bf74d716c2f5e1b", updatedAt: "2018-11-09T22:46:21.445Z",
createdAt: "2018-11-09T22:46:21.445Z", name: "Gemini Twin 3 Batch 11-9 2:45", brewerName: "Gemini", …}
1: {_id: "5be60eb58bf74d716c2f5e1c", updatedAt: "2018-11-09T22:48:21.443Z", createdAt: "2018-11-09T22:48:21.443Z", name: "Gemini Twin 3 Batch 11-9 2:45", brewerName: "Gemini", …}
length: 2
__proto__: Array(0)
headers: {Accept: "application/json, text/plain, */*", Content-Type: "application/json;charset=utf-8", Authorization: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYW1lIjoid…Dc5fQ.JPVQkZUaJ2651gyC1_L5jTiLQGAy3PxNjPbAGrPkm4s"}
jsonpCallbackParam: "callback"
method: "POST"
paramSerializer: ƒ (a)
transformRequest: [ƒ]
transformResponse: [ƒ]
url: "/createFile"
__proto__: Object
data: "↵&2B����LX�������=s�����}]= � �↵��}
]=����}�����������������������������������������������������������������������������{g]U"
headers: ƒ (d)
status: 200
statusText: "OK"
xhrStatus: "complete"
__proto__: Object
解决方案
通过将数据传送到前端而不是 res.download 解决了这个问题,并告诉 angularjs 在 http 请求 res 中期待一个 blob
节点服务器
createFile: function(req,res){
console.log('server reciped recipes', req.body[0], req.body[1]);
console.log('from user', req.body[1]);
createRecipeFile.writeRecipe(req.body[0], req.body[1])
user = req.body[1];
var file = 'server/generatedFiles/'+user+'.REL'
fs.access(file, fs.constants.R_OK, (err) => {
if (err){
console.log('err', err);
} else{
var count = 0
console.log('reading stream');
var fReadStream = fs.createReadStream(file);
fReadStream.pipe(res);
}
})
},
AngularJS 工厂
factory.generateFile = function(recipes, user, callback){
console.log('factory recieved recipes', recipes, user);
$http({
url: '/createFile',
method: 'POST',
data: [recipes, user],
responseType: 'blob'
}).then(function(res){
console.log('generate file res1', res, res.data);
console.log('recieved data length', res.data.length);
var file = res.data;
FileSaver.saveAs(file, 'g4R12.REL')
},function(res){
console.log('generate file res2', res);
})
}
推荐阅读
- linux - 在任何 Unix Shell 上,“--”和“-”是什么意思?
- maven - 在微服务之间共享 DTO
- python - self 在这个 Distribution 类中做了什么?
- c++ - 我怎么能用winsock2用c++做https请求
- javascript - 如何在 HighChart 中设置 y 轴?
- reactjs - React App 调用“aws s3 sync”将客户端本地文件夹上传到 s3
- c# - 如何在 Azure TableController 中注入公共服务依赖项
- python - 多层感知器梯度消失
- ios - 使用 Swift IOS 在不同 ViewController 中的相同功能
- android - 用于代码生成的 ANTLR Tool 版本 4.5.3 与当前运行时版本 4.7.1 不匹配