所以我在将文件上传到服务器后尝试将文件提供给用户。我将上传的文件存储在应用程序目录中的一个名为uploads的目录中。这是我用来提供文件的代码:
if (req.url.split("/")[1] == "uploads") {
console.log("requesting file " + virtualToPhysical(req.url));
var file = fs.readFile(virtualToPhysical(req.url), function (err, data) {
if (err) {
throw err;
} else {
res.writeHead(200, { 'Content-Type': mime.lookup(req.url) });
res.end(data, 'binary');
}
});
}
virtualToPhysical只是将文件系统中目录的路径附加到请求URL上。如果req.url是“/uploads/image1.jpg”,则virtualToPhysical将吐出“/path/to/application/uploads/image1.jpg”。 mime.lookup()调用来自一个包含的库,它推导出文件的正确MIME类型。
此代码运行时没有任何错误。响应标题看起来没问题,但无论文件类型或大小如何,每次都会将空体返回为空。我尝试了另一种方法usinng util.pump()但产生了相同的结果。
* 编辑: *我一直在四处寻找,这实际上是人们说用来通过节点提供文件的唯一方法。我不知道我的问题是什么。有人建议在调用res.end()时不使用'binary'标志,但无论如何都会产生相同的效果。
答案 0 :(得分:0)
从您对'binary'
的通话中删除res.end()
参数; encoding
参数仅在您发送字符串时适用,在这种情况下您将发送缓冲区。此外,'binary'
在最新版本的节点中作为编码类型被删除。
答案 1 :(得分:0)
我发现问题不在fs.readFile
打开文件,这是我在上传时保存文件的方式。您需要从/ tmp中的位置重命名,而不是在从强大的文件中保存上传时使用fs.writeFile()
。这是一个例子:
form.parse(req, function (err, fields, files) {
file_name = escape(files.upload.name);
fs.rename(files.upload.path, virtualToPhysical("/uploads/" + file_name), function (err) {
if (err) {
throw err;
} else {
res.writeHead(200, {'Content-Type': 'text/html'});
res.end(file_name);
}
});
});