Nodejs静态图片文件输出错误的问题
Nodejs静态图片文件输出错误的问题
静态文件的读取是参照Jackson的文章 用NodeJS打造你的静态文件服务器
var http = require("http");
var fs = require("fs");
var url = require("url");
var path = require("path");
var mine = require("./mime");
http.createServer(function(req, res){
var pathname = url.parse(req.url).pathname;
var ext = path.extname(pathname) || "unknow";
fs.readFile(__dirname + pathname, "utf8", function(err, content){
if(!err){
res.writeHead(200, {
'Content-Type': mine.types[ext]
});
res.write(content);
res.end();
}
});
}).listen(8080, function(){
console.log("server started");
})
mime.js:
exports.types = {
".css" : "text/css",
".html" : "text/html",
".js" : "text/javascript",
".png" : "image/png",
".gif" : "image/gif",
".jpg" : "image/jpg",
".jpeg" : "image/jpeg",
".ico" : "image/x-icon",
"unknow" : "text/plain"
}
在我访问localhost:8080/index.html的时候html文件,js文件,json文件都没问题,但是图片的请求都抛出这样的错误:
Image corrupt or truncated: http://localhost:8080/static/images/black_che.png
Image corrupt or truncated: http://localhost:8080/static/images/black_ma.png
Image corrupt or truncated: http://localhost:8080/static/images/black_xiang.png
Image corrupt or truncated: http://localhost:8080/static/images/black_shi.png
Image corrupt or truncated: http://localhost:8080/static/images/black_jiang.png
Image corrupt or truncated: http://localhost:8080/static/images/black_pao.png
Image corrupt or truncated: http://localhost:8080/static/images/black_zu.png
Image corrupt or truncated: http://localhost:8080/static/images/red_pao.png
Image corrupt or truncated: http://localhost:8080/static/images/red_bing.png
Image corrupt or truncated: http://localhost:8080/static/images/red_che.png
Image corrupt or truncated: http://localhost:8080/static/images/red_ma.png
Image corrupt or truncated: http://localhost:8080/static/images/red_xiang.png
Image corrupt or truncated: http://localhost:8080/static/images/red_shi.png
Image corrupt or truncated: http://localhost:8080/static/images/red_shuai.png
这里对图片静态文件需要做什么额外处理吗?
Nodejs静态图片文件输出错误的问题
在使用Node.js搭建静态文件服务器时,遇到静态图片文件输出错误的问题。根据提供的代码,可以看到当前的代码存在一些问题,特别是在读取二进制文件(如图片)时使用了错误的方式。
问题分析
在原始代码中,图片文件被当作文本文件来处理,通过 fs.readFile
方法以字符串形式读取文件内容,并设置响应头的 Content-Type
。对于图片文件来说,直接将它们作为字符串处理会导致数据损坏,从而导致浏览器无法正确解析这些图片。
解决方案
为了正确处理图片文件,我们需要将它们作为二进制数据进行读取,并设置适当的 Content-Type
。以下是修改后的代码示例:
var http = require("http");
var fs = require("fs");
var url = require("url");
var path = require("path");
var mime = require("./mime");
http.createServer(function (req, res) {
var pathname = url.parse(req.url).pathname;
// 检查文件是否存在
fs.access(__dirname + pathname, fs.constants.F_OK, function (err) {
if (err) {
// 文件不存在,返回404错误
res.writeHead(404, { "Content-Type": "text/plain" });
res.write("404 Not Found\n");
res.end();
return;
}
// 获取文件扩展名
var ext = path.extname(pathname) || "unknow";
// 设置正确的Content-Type
res.setHeader('Content-Type', mime.types[ext] || "application/octet-stream");
// 以二进制模式读取文件
fs.readFile(__dirname + pathname, function (err, content) {
if (!err) {
// 发送文件内容
res.end(content);
} else {
// 文件读取失败,返回500错误
res.writeHead(500, { "Content-Type": "text/plain" });
res.write("500 Internal Server Error\n");
res.end();
}
});
});
}).listen(8080, function () {
console.log("server started");
});
解释
- 检查文件是否存在:使用
fs.access
方法检查请求的文件是否存在于服务器上。 - 设置正确的 Content-Type:根据文件扩展名设置响应头中的
Content-Type
。 - 读取二进制数据:使用
fs.readFile
方法以二进制模式读取文件内容,并通过res.end(content)
发送文件内容。
通过上述修改,可以确保图片文件能够正确地被读取并发送到客户端,避免出现图片损坏或截断的问题。
读取图片文件时,直接以Buffer方式读出,不要指定字符编码:
fs.readFile(__dirname + pathname, function(err, content){
// ....
});
你代码中的s.readFile(__dirname + pathname, "utf8", ...)
是不对的
额 ,问题解决了,是自己没认真看代码 :(,用"binary"读取,"binary"输出。
嗯嗯 已经搞定了
我的代码是在readLine函数里面指定编码是"binary",在write函数里面输出制定编码方式是"binary",但是图片不能正确显示,但是去掉readLine函数里面的第二个参数,就是编码方式"binary",图片却能正确显示。不知道为什么,求解?
在处理图片文件时,需要确保文件是以二进制模式(binary
或 base64
)读取的,而不是以文本模式(例如 utf8
)。你在代码中使用了 "utf8"
编码来读取文件内容,这会导致图片文件被错误地解码。
以下是修改后的示例代码:
var http = require("http");
var fs = require("fs");
var url = require("url");
var path = require("path");
var mine = require("./mime");
http.createServer(function(req, res){
var pathname = url.parse(req.url).pathname;
var ext = path.extname(pathname) || "unknown";
fs.readFile(__dirname + pathname, function(err, content){
if (!err) {
res.writeHead(200, {
'Content-Type': mine.types[ext]
});
res.end(content); // 直接输出二进制内容
} else {
res.writeHead(404);
res.end("File not found");
}
});
}).listen(8080, function(){
console.log("Server started");
});
在这个示例中,fs.readFile
函数不再指定编码方式(默认为二进制),并直接将文件内容通过 res.end(content)
输出。这样可以确保图片文件不会被错误解码。