使用 AngularJS 从 Node.JS 服务器下载文件
Download a file from Node.JS server with AngularJS
我想用我的浏览器从我的服务器 运行 NodeJS 下载文件。
在服务器端,提供我拥有的文件:
exports.download = function(req, res) {
var filename = "33.jpg";
var filePath = path.join(__dirname, '..', '..', 'downloads', filename);
var stat = fs.statSync(filePath);
var fileToSend = fs.readFileSync(filePath);
res.writeHead(200, {
'Content-Type': 'image/jpeg',
'Content-Length': stat.size,
'Content-Disposition': filename
});
res.end(fileToSend);
};
名为 33.jpg 的文件存在并且大小为 744Kb。客户来电效果很好
在客户端 AngularJS 下面是我如何调用 post 调用来获取文件(当前未使用参数 uri):
$scope.downloadTrack = function(uri) {
$http.post('/api/files/download', {uri: uri}).then(function(response) {
var blob = new Blob([response.data], { type: 'image/jpeg' });
var fileName = response.headers('content-disposition');
saveAs(blob, fileName);
}, function(response) {
console.log('Download error');
console.log(response);
});
}
headers没问题(我可以找回文件名)
我的问题是下载了一个文件,但大小为 1.5Mb,无法读取。我尝试了不同的流方法,将数据附加到响应、管道等,但没有成功。
另一点(不确定是否重要):在 Safari 中打开文件时显示损坏的图标,在 Chrome 中保存文件
PS : 如果信息有用,我用 Yeoman 创建了项目
谢谢大家
[更新]
新版服务器功能(还不能用)
exports.download = function(req, res) {
var filename = "33.jpg";
var filePath = path.join(__dirname, '..', '..', 'downloads', filename);
var stat = fs.statSync(filePath);
var fileToSend = fs.readFileSync(filePath);
res.set('Content-Type', 'image/jpeg');
res.set('Content-Length', stat.size);
res.set('Content-Disposition', filename);
res.send(fileToSend);
};
[更新 2]
双倍大小的文件在文件中随机包含额外的 "efbffd" 字符序列,使其无法读取
您使用 res#end
而不是 res#send
(带有 S)来发送响应的头部而不是正文。
exports.download = function(req, res) {
// ...
res.send(fileToSend);
};
来自 Express documentation 对于 res#end
:
Use to quickly end the response without any data. If you need to respond with data, instead use methods such as res.send() and res.json().
通过将响应类型定义设置为 blob
解决了问题
$http({
url: '/api/files/download',
method: "POST",
data: {
uri: uri
},
responseType: 'blob'
}).then(function (response) {
var data = response.data;
var headers = response.headers;
var blob = new Blob([data], { type: 'audio/mpeg' });
var fileName = headers('content-disposition');
saveAs(blob, fileName);
}).catch(function (response) {
console.log('Unable to download the file')
});
我想用我的浏览器从我的服务器 运行 NodeJS 下载文件。 在服务器端,提供我拥有的文件:
exports.download = function(req, res) {
var filename = "33.jpg";
var filePath = path.join(__dirname, '..', '..', 'downloads', filename);
var stat = fs.statSync(filePath);
var fileToSend = fs.readFileSync(filePath);
res.writeHead(200, {
'Content-Type': 'image/jpeg',
'Content-Length': stat.size,
'Content-Disposition': filename
});
res.end(fileToSend);
};
名为 33.jpg 的文件存在并且大小为 744Kb。客户来电效果很好
在客户端 AngularJS 下面是我如何调用 post 调用来获取文件(当前未使用参数 uri):
$scope.downloadTrack = function(uri) {
$http.post('/api/files/download', {uri: uri}).then(function(response) {
var blob = new Blob([response.data], { type: 'image/jpeg' });
var fileName = response.headers('content-disposition');
saveAs(blob, fileName);
}, function(response) {
console.log('Download error');
console.log(response);
});
}
headers没问题(我可以找回文件名)
我的问题是下载了一个文件,但大小为 1.5Mb,无法读取。我尝试了不同的流方法,将数据附加到响应、管道等,但没有成功。 另一点(不确定是否重要):在 Safari 中打开文件时显示损坏的图标,在 Chrome 中保存文件
PS : 如果信息有用,我用 Yeoman 创建了项目
谢谢大家
[更新] 新版服务器功能(还不能用)
exports.download = function(req, res) {
var filename = "33.jpg";
var filePath = path.join(__dirname, '..', '..', 'downloads', filename);
var stat = fs.statSync(filePath);
var fileToSend = fs.readFileSync(filePath);
res.set('Content-Type', 'image/jpeg');
res.set('Content-Length', stat.size);
res.set('Content-Disposition', filename);
res.send(fileToSend);
};
[更新 2] 双倍大小的文件在文件中随机包含额外的 "efbffd" 字符序列,使其无法读取
您使用 res#end
而不是 res#send
(带有 S)来发送响应的头部而不是正文。
exports.download = function(req, res) {
// ...
res.send(fileToSend);
};
来自 Express documentation 对于 res#end
:
Use to quickly end the response without any data. If you need to respond with data, instead use methods such as res.send() and res.json().
通过将响应类型定义设置为 blob
解决了问题 $http({
url: '/api/files/download',
method: "POST",
data: {
uri: uri
},
responseType: 'blob'
}).then(function (response) {
var data = response.data;
var headers = response.headers;
var blob = new Blob([data], { type: 'audio/mpeg' });
var fileName = headers('content-disposition');
saveAs(blob, fileName);
}).catch(function (response) {
console.log('Unable to download the file')
});