《Nodejs入门》一书中代码存在的问题
《Nodejs入门》一书中代码存在的问题
<p>《Nodejs入门》一书确实很好的入门工具书,不过其中的一些代码还是和我们的实际开发环境不同。比如该书中的最后一个例子,上传图片到服务器。</p>
<p>其中存在的问题的一部分源代码如下(处理上传文件):</p>
<p>Js代码 </p>
<pre><code>function upload( res, req){
console.log(“request upload mehtod”);
var form = new formidable.IncomingForm();
form.parse( req, function( error, fields, files){
fs.renameSync(files.upload.path, “tmp/”+filename+".png");
res.writeHead(200,{“Content-Type”:“text/html”});
res.write("<img src=’/show’/>"); //发送/show请求
res.end();
});
}
</code></pre>
<p>这里用到了formidable第三方模块,上面的代码总是报错“can not find File or Directory: c:…”; 原因是formidable默认上传文件的保存路径与项目路径不在同一相同路径中。如我的工程是在e盘。所以需要设置form.uploadDir = “tmp”;//指向工程中的tmp文件夹</p>
<p>另外,fs.renameSync()保存文件会抛出异常,为了能让程序正常运行,这里需要添加try{}catch(e){}</p>
<p>如果我们像上传图片的同时,想在前台的一个输入框内设置一下名称,后台通过formidable如何获取这个字段的值呢?</p>
<p>Js代码 </p>
<pre><code>…
form.parse(req, function(error, fields, files){
//filename为<input>标签中name属相的值
var filename = fields["filename"];
…
});
…
</code></pre>
<p>综上所述下面是upload方法完整的代码:</p>
<p>Js代码 </p>
<pre><code>function upload( res, req){
console.log(“request upload mehtod”);
var form = new formidable.IncomingForm();
form.uploadDir = "tmp";
form.parse( req, function( error, fields, files){
console.log("parsing done");
var filename = fields['filename'];
console.log("filename = " + filename);
try{
fs.renameSync(files.upload.path, “tmp/”+filename+".png");
}catch( e){
console.log(e);
}
res.writeHead(200,{“Content-Type”:“text/html”});
res.write("<img src=’/show’/>"); //发送/show请求
res.end();
});
}
</code></pre>
根据你提供的内容,《Node.js 入门》一书中关于上传图片的例子确实存在一些问题。这些问题主要涉及到文件路径、错误处理以及表单数据的正确解析。以下是修正后的完整代码示例,并附带简要解释:
原始存在问题的代码
function upload(res, req) {
console.log("request upload method");
var form = new formidable.IncomingForm();
form.parse(req, function (error, fields, files) {
fs.renameSync(files.upload.path, "tmp/" + filename + ".png");
res.writeHead(200, {"Content-Type": "text/html"});
res.write("<img src='/show'/>");
res.end();
});
}
存在的问题:
fs.renameSync
中的filename
变量未定义。formidable
默认的上传目录可能与预期不符,需要显式设置。- 没有错误处理机制。
修正后的代码
const formidable = require('formidable');
const fs = require('fs');
function upload(res, req) {
console.log("request upload method");
// 设置上传文件的临时存储目录
const form = new formidable.IncomingForm();
form.uploadDir = 'tmp';
form.parse(req, function (error, fields, files) {
if (error) {
console.error("Error parsing form:", error);
res.writeHead(500, {"Content-Type": "text/plain"});
res.end("Internal Server Error");
return;
}
// 获取用户上传的文件名
const filename = fields['filename'];
console.log("Filename =", filename);
try {
// 重命名并移动上传的文件
fs.renameSync(files.upload.path, `tmp/${filename}.png`);
} catch (e) {
console.error("Error renaming file:", e);
res.writeHead(500, {"Content-Type": "text/plain"});
res.end("Internal Server Error");
return;
}
// 返回成功的响应
res.writeHead(200, {"Content-Type": "text/html"});
res.write("<img src='/show'/>");
res.end();
});
}
解释:
- 设置上传目录:通过
form.uploadDir
显式指定上传文件的临时存储目录。 - 错误处理:在
form.parse
的回调函数中增加错误处理逻辑,确保如果发生错误能够返回适当的 HTTP 状态码和错误信息。 - 变量使用:正确地使用
fields['filename']
来获取前端表单提交的文件名,并将其与上传的文件关联起来。 - 日志记录:增加更多的日志记录来帮助调试。
通过这些改进,代码将更加健壮且易于维护,能够更好地处理实际开发环境中的各种情况。
彼此彼此,共同学习~
已经跟进了。还跟进了《nodejs入门》中提到的nodejs不支持缓存,使用eclipse插件来查看数据传递的问题。
我也看了,照着示例敲代码,看到那个以非阻塞方式来访问页面的时候,怎么一直都是阻塞的,页面一直加载,根本进不去。 var exec = require(“child_process”).exec;
function start() { console.log(“Request handler ‘start’ was called.”); var content = “empty”;
exec(“ls -lah”, function (error, stdout, stderr) { content = stdout; });
return content; }
function upload() { console.log(“Request handler ‘upload’ was called.”); return “Hello Upload”; }
exports.start = start; exports.upload = upload;
不知道怎么回事
自己回答下,因为我用的是window下安装node,没有源码和类库,所以导致这个问题…我试了下cygwin下 是wonderful。。。哈哈
我当时遇到一个问题,是安装了迅雷的游戏加速器。导致LSP被修改了。导致无法访问。一直等待状态。你看看是不是也是类似的问题。至于书里面写的那段例子我测试是没有问题的。我在windows下就OK。
看到帖子都是2012年的…
So…what?
根据你的描述,《Node.js 入门》一书中关于文件上传的代码存在几个问题,这些问题可能会影响代码的正常运行。以下是详细的修正建议:
1. 设置 uploadDir
路径
formidable
默认的文件保存路径可能会导致找不到文件目录的问题。你需要显式地设置 uploadDir
属性以指定一个有效的路径。
form.uploadDir = path.join(__dirname, 'tmp');
2. 使用 fs.rename
替代 fs.renameSync
使用同步的 fs.renameSync
方法会阻塞事件循环,影响性能。推荐使用异步版本的 fs.rename
方法,这样可以避免阻塞。
fs.rename(files.upload.path, "tmp/" + filename + ".png", (err) => {
if (err) {
console.error("Error renaming file:", err);
} else {
console.log("File renamed successfully");
}
});
3. 完整的 upload
方法
结合上述修改,完整的 upload
方法应该如下所示:
const formidable = require('formidable');
const fs = require('fs');
const path = require('path');
function upload(res, req) {
console.log("Request upload method");
const form = new formidable.IncomingForm();
form.uploadDir = path.join(__dirname, 'tmp');
form.parse(req, (error, fields, files) => {
console.log("Parsing done");
const filename = fields['filename'];
console.log("Filename =", filename);
if (!filename) {
console.error("No filename provided");
return;
}
fs.rename(files.upload.path, "tmp/" + filename + ".png", (err) => {
if (err) {
console.error("Error renaming file:", err);
res.writeHead(500, {"Content-Type": "text/html"});
res.write("<h1>Upload Failed</h1>");
} else {
console.log("File renamed successfully");
res.writeHead(200, {"Content-Type": "text/html"});
res.write("<img src='/show' />"); // 发送/show请求
}
res.end();
});
});
}
总结
以上是基于你的描述对书中代码进行的修正。这些修改主要是为了提高代码的健壮性和可维护性。确保在实际部署时,tmp
文件夹存在且具有适当的权限。