Nodejs入门遇到的问题,formidable上传图片时报错

Nodejs入门遇到的问题,formidable上传图片时报错

基本上是根据Nodejs入门一步步做的,代码也基本一样: index.js:

var server = require('./server.js');
var router = require('./router.js');
var requestHandlers = require('./requestHandlers.js');

var handle = {};
handle['/'] = requestHandlers.start;
handle['/start'] = requestHandlers.start;
handle['/upload'] = requestHandlers.upload;
handle['/show'] = requestHandlers.show;

server.start(router.route,handle);

server.js:

var http = require("http");
var url = require('url');
exports.start = function(route, handle){
	http.createServer(function(request, response){
		var pathname = url.parse(request.url).pathname;
		route(handle, pathname, response, request);
	}).listen(3000);
	console.log('Server has started!');
};

router.js:

function route (handle, pathname, response, request) {
	console.log('A request for' + pathname);

	if(typeof handle[pathname] === 'function'){
		handle[pathname](response, request);
	}else{
		console.log('No request handler for ' + pathname);

		response.writeHead(404, {'Content-Type': 'text/plain'});
		response.write('404 not found');
		response.end();
	}
}
exports.route = route;

requestHandler.js:

var querystring = require('querystring'),
	fs = require('fs'),
	formidable = require('formidable'),
	util = require('util');

function start (response) {
	console.log('Request handler "start" was called.');

	var body = '<html>'+
			    '<head>'+
			    '<meta http-equiv="Content-Type" content="text/html; '+
			    'charset=UTF-8" />'+
			    '</head>'+
			    '<body>'+
			    '<form action="/upload" method="post" enctype="multipart/form-data">'+
			    '<input type="file" name="upload" multiple="multiple">'+
    			'<input type="submit" value="Upload file" />'+
			    '</form>'+
			    '</body>'+
			    '</html>';
	response.writeHead(200, {'Content-Type': 'text/html'});
	response.write(body);
	response.end();
}
function upload (response, request) {
	console.log('Request handler "upload" was called.');

	var form = new formidable.IncomingForm();
	form.uploadDir = 'tmp';
	form.parse(request, function(error, fields, files){
		//fs.renameSync(files.upload.path, '/tmp/test.png');
		try{
			console.log(files.upload.path);
		}catch(e){
			console.log(e);
		}
		response.writeHead(200, {'Content-Type': 'text/html'});
		response.write('Received image: <br>');
		response.write('<img src="/show" />');
		response.end();
	});
	
}
function show (response) {
	console.log('Request handler "show" was called.');
	fs.readFile('/tmp/test.png', 'binary', function(error, file) {
		if(error){
			response.writeHead(500, {'Content-Type': 'text/plain'});
			response.write(error + '\n');
			response.end();
		}else{
			response.writeHead(200, {'Content-Type': 'image/png'});
			response.write(file, 'binary');
			response.end();
		}
	});
}
exports.start = start;
exports.upload = upload;
exports.show = show;

###报错信息:

Cannot read property ‘path’ of undefined

####打印files的结果:

{ upload:
   { domain: null,
     _events: {},
     _maxListeners: 10,
     size: 2722,
     path: 'tmp\\2d3ead58151f69465f4fec03b2e27b34',
     name: 'image-holder.png',
     type: 'image/png',
     hash: null,
     lastModifiedDate: Tue May 06 2014 16:44:50 GMT+0800 (中国标准时间),
     _writeStream:
      { _writableState: [Object],
        writable: true,
        domain: null,
        _events: {},
        _maxListeners: 10,
        path: 'tmp\\2d3ead58151f69465f4fec03b2e27b34',
        fd: null,
        flags: 'w',
        mode: 438,
        start: undefined,
        pos: undefined,
        bytesWritten: 2722,
        closed: true } } }

之前看到有人提过这个问题 链接 ,是因为自己设置了encoding,但是我没设置也是这个问题,各位大神帮忙看一下到底哪里有问题啊


11 回复

Nodejs入门遇到的问题,formidable上传图片时报错

基本上是根据Nodejs入门一步步做的,代码也基本一样:

index.js

var server = require('./server.js');
var router = require('./router.js');
var requestHandlers = require('./requestHandlers.js');

var handle = {};
handle['/'] = requestHandlers.start;
handle['/start'] = requestHandlers.start;
handle['/upload'] = requestHandlers.upload;
handle['/show'] = requestHandlers.show;

server.start(router.route, handle);

server.js

var http = require("http");
var url = require('url');

exports.start = function(route, handle) {
    http.createServer(function(request, response) {
        var pathname = url.parse(request.url).pathname;
        route(handle, pathname, response, request);
    }).listen(3000);
    console.log('Server has started!');
};

router.js

function route(handle, pathname, response, request) {
    console.log('A request for ' + pathname);

    if (typeof handle[pathname] === 'function') {
        handle[pathname](response, request);
    } else {
        console.log('No request handler for ' + pathname);

        response.writeHead(404, {'Content-Type': 'text/plain'});
        response.write('404 not found');
        response.end();
    }
}

exports.route = route;

requestHandler.js

var querystring = require('querystring'),
    fs = require('fs'),
    formidable = require('formidable'),
    util = require('util');

function start(response) {
    console.log('Request handler "start" was called.');

    var body = '<html>' +
               '<head>' +
               '<meta http-equiv="Content-Type" content="text/html; ' +
               'charset=UTF-8" />' +
               '</head>' +
               '<body>' +
               '<form action="/upload" method="post" enctype="multipart/form-data">' +
               '<input type="file" name="upload" multiple="multiple">' +
               '<input type="submit" value="Upload file" />' +
               '</form>' +
               '</body>' +
               '</html>';
    response.writeHead(200, {'Content-Type': 'text/html'});
    response.write(body);
    response.end();
}

function upload(response, request) {
    console.log('Request handler "upload" was called.');

    var form = new formidable.IncomingForm();
    form.uploadDir = 'tmp';
    form.parse(request, function(error, fields, files) {
        if (error) {
            console.error(error);
            response.writeHead(500, {'Content-Type': 'text/plain'});
            response.write('Error processing the request.\n');
            response.end();
            return;
        }

        try {
            console.log(files.upload.path);
        } catch (e) {
            console.log(e);
        }

        response.writeHead(200, {'Content-Type': 'text/html'});
        response.write('Received image: <br>');
        response.write('<img src="/show" />');
        response.end();
    });
}

function show(response) {
    console.log('Request handler "show" was called.');
    fs.readFile('/tmp/test.png', 'binary', function(error, file) {
        if (error) {
            response.writeHead(500, {'Content-Type': 'text/plain'});
            response.write(error + '\n');
            response.end();
        } else {
            response.writeHead(200, {'Content-Type': 'image/png'});
            response.write(file, 'binary');
            response.end();
        }
    });
}

exports.start = start;
exports.upload = upload;
exports.show = show;

报错信息:

Cannot read property ‘path’ of undefined

打印files的结果:

{ upload:
   { domain: null,
     _events: {},
     _maxListeners: 10,
     size: 2722,
     path: 'tmp\\2d3ead58151f69465f4fec03b2e27b34',
     name: 'image-holder.png',
     type: 'image/png',
     hash: null,
     lastModifiedDate: Tue May 06 2014 16:44:50 GMT+0800 (中国标准时间),
     _writeStream:
      { _writableState: [Object],
        writable: true,
        domain: null,
        _events: {},
        _maxListeners: 10,
        path: 'tmp\\2d3ead58151f69465f4fec03b2e27b34',
        fd: null,
        flags: 'w',
        mode: 438,
        start: undefined,
        pos: undefined,
        bytesWritten: 2722,
        closed: true } } }

解决方法

问题出在form.parse()回调函数中,如果files对象中的属性名与表单字段的名称不匹配,那么files.upload将不存在,从而导致无法读取path属性。

upload函数中,确保files对象中的属性名与表单字段的名称一致。例如,如果表单字段名为upload,则应使用files.upload来访问文件路径。

form.parse(request, function(error, fields, files) {
    if (error) {
        console.error(error);
        response.writeHead(500, {'Content-Type': 'text/plain'});
        response.write('Error processing the request.\n');
        response.end();
        return;
    }

    // 确保文件字段名称正确
    if (files.upload) {
        console.log(files.upload.path);
    } else {
        console.log('No file uploaded.');
    }

    response.writeHead(200, {'Content-Type': 'text/html'});
    response.write('Received image: <br>');
    response.write('<img src="/show" />');
    response.end();
});

确保表单字段名称与IncomingForm实例中的字段名称一致,以避免此类错误。


console.log(files)是可以读出的

form.uploadDir = ‘tmp’;

可能是这个问题,路径错误。

form.uploadDir = “/my/dir”;这个是formidable的例子

应该不是,这个是我后来加的,开始是默认。而且我看tmp目录里已经写入临时文件

相应的目录下面要建立相应的文件夹,如果没有的话,node不会自动建立,而是报错

文件夹已经创建了

问题解决了么……

入门就学框架? 没意思。我觉得正式学一个框架之前起码最好自己可以实现简单的框架

根据你的描述和提供的代码,错误信息 Cannot read property 'path' of undefined 表明在调用 files.upload.path 时,files.upload 可能为 undefined。这通常发生在表单数据解析过程中出现问题。

以下是可能的原因及解决方法:

  1. 检查表单字段名称: 确保在HTML表单中的 <input> 元素的 name 属性与你在服务器端处理程序中使用的字段名一致。你使用的是 name="upload",确保在 form.parse 的回调函数中,字段名也正确匹配。

    form.parse(request, function(error, fields, files){
        console.log(files); // 检查是否有 upload 字段
        if (files.upload) {
            console.log(files.upload.path);
        } else {
            console.error('File upload not found');
        }
        // 继续其他逻辑
    });
    
  2. 检查 enctype 属性: 确保表单的 enctype 属性设置为 multipart/form-data,因为这是文件上传必需的。

  3. 检查浏览器开发者工具: 使用浏览器的开发者工具(如 Chrome 的 DevTools)查看网络请求,确认文件是否成功发送到服务器。

  4. 处理错误: 确保在 form.parse 回调中处理所有潜在错误,并进行适当的日志记录。

如果你已经检查了以上几点但问题仍然存在,建议重新检查整个文件上传流程,确保每个步骤都按预期工作。如果问题依然没有解决,请提供更多的上下文或错误堆栈信息以便进一步诊断。

回到顶部