Nodejs得到页面图片混乱

Nodejs得到页面图片混乱

本人初学node尝试了一个简单的静态服务器,仅仅返回一个拥有五张图片的页面,不过发现这五张图片的显示的不正确

var http = require(“http”), fs = require(“fs”), base = ‘www/img/’, mime = require(“mime”);

http.createServer(function(req, res){ pathname = base + req.url; var type = mime.lookup(pathname); console.log(pathname); fs.exists(pathname, function(exists){ if(exists){ var file = fs.readFile(pathname, “binary”, function(err, data){ if(!err){ res.setHeader(“Content-Type”,type); res.write(data, “binary”); res.end(); }else{ console.log(err); } }) }else{ res.writeHead(404,{“Content-Type”:“text/plain”}); res.write(“Bad request 404\n”); res.end(); } }); }).listen(8080);

然后页面每一次刷新显示的图片都会不一样 这个是正确的时候 1.png 比如我再一次刷新 2.png 就会变成这样子,每一次刷新都有新的惊喜,但是看到html源码中对应的图片src都是正确的 这情况是不是因为回调冲突了这样的情况啊,求讲解。。。


7 回复

针对你提到的Node.js服务端代码,你遇到的问题可能是由于文件读取操作没有完全完成就被返回给了客户端,导致部分内容丢失。此外,你的代码没有处理二进制数据的方式可能也不够规范。这里提供一种改进后的解决方案,并附上代码示例。

改进后的代码

const http = require('http');
const fs = require('fs');
const path = require('path');
const mime = require('mime');

const server = http.createServer((req, res) => {
    const pathname = path.join(__dirname, 'www', 'img', req.url);

    fs.access(pathname, (err) => {
        if (err) {
            // 文件不存在时返回404错误
            res.writeHead(404, {"Content-Type": "text/plain"});
            res.end("Not Found");
            return;
        }

        const type = mime.getType(pathname);
        fs.readFile(pathname, (err, data) => {
            if (err) {
                console.error(`Error reading file: ${pathname}`, err);
                res.writeHead(500, {"Content-Type": "text/plain"});
                res.end("Internal Server Error");
                return;
            }
            
            // 设置响应头
            res.setHeader("Content-Type", type);
            // 发送二进制数据
            res.end(data);
        });
    });
});

server.listen(8080, () => {
    console.log('Server running at http://localhost:8080/');
});

解释

  1. 使用path.join来构建路径:这有助于避免路径拼接中的错误,并且自动处理跨平台兼容性问题。

  2. 使用fs.access代替fs.existsfs.access提供了更好的错误处理机制,并且不会在文件存在的情况下读取文件,从而减少不必要的IO操作。

  3. 正确处理二进制数据:直接使用fs.readFile读取整个文件内容,不需要手动设置"binary"模式,因为Node.js默认处理二进制数据。

  4. 添加错误处理:确保在文件读取或写入过程中出现任何错误时,能够及时响应并记录错误信息。

通过这些修改,应该可以解决图片加载混乱的问题。如果你仍然遇到问题,请检查浏览器缓存或网络连接是否存在问题。


图片的URL是怎么写的

[@coolicer](/user/coolicer) 和html文件在同一目录,图片的URL是相对定位。。我如果用node打开页面看源码哪怕图片显示的不对,可是我找到那个图片的元素结点,看它的URL,找过去却是对的,只不过显示出来的不对

应该是异步的原因吧?你把你读取图片的方法改成同步的试试

全部代码打包,帮你看一下

fs.exists(pathname, function(exists){ pathname }) 是个异步回调,等到响应过来之后,回调里的pathname已经不一定对应req.url了。加个匿名函数确保pathname对应上即可。

(function(pathname){
	fs.exists(pathname, function(exists){
		pathname
	})
})(pathname)

根据你的描述,页面中的图片每次刷新时显示不同,但HTML源码中的图片路径看起来是正确的。这种现象可能是由于以下几个原因导致的:

  1. 缓存问题:浏览器可能在缓存中存储了旧的图片文件,导致即使文件被更新,浏览器仍然显示旧的图片。
  2. 读取文件顺序问题:虽然不太可能,但文件读取顺序可能会导致浏览器解析图片路径时出现混淆。

为了排除缓存问题,你可以通过添加时间戳到请求URL上来强制浏览器每次都从服务器加载新的资源。

修改后的代码

var http = require("http");
var fs = require("fs");
var path = require("path");
var mime = require("mime");

http.createServer(function (req, res) {
    var pathname = path.join(__dirname, 'www', 'img', req.url.split('?')[0]);
    
    // 添加时间戳来防止缓存问题
    if (req.url.includes('?')) {
        res.writeHead(404, {"Content-Type": "text/plain"});
        res.write("Bad request 404\n");
        res.end();
        return;
    }
    
    var type = mime.lookup(pathname);

    fs.exists(pathname, function (exists) {
        if (exists) {
            fs.readFile(pathname, "binary", function (err, data) {
                if (!err) {
                    res.setHeader("Content-Type", type);
                    res.write(data, "binary");
                    res.end();
                } else {
                    console.log(err);
                }
            });
        } else {
            res.writeHead(404, {"Content-Type": "text/plain"});
            res.write("Bad request 404\n");
            res.end();
        }
    });
}).listen(8080);

解释

  1. 路径处理:使用path.join来确保路径拼接正确。
  2. 防缓存处理:检查请求URL是否包含查询字符串(即时间戳),如果有则返回404错误。
  3. 错误处理:在文件不存在或读取失败时返回404错误。

通过这种方式,你可以确保每次请求都会从服务器获取最新的图片文件,从而避免浏览器缓存问题导致的显示混乱。

回到顶部