《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为&lt;input&gt;标签中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("&lt;img src=’/show’/&gt;"); //发送/show请求
res.end();
});

}
</code></pre>


13 回复

根据你提供的内容,《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();
    });
}

存在的问题:

  1. fs.renameSync 中的 filename 变量未定义。
  2. formidable 默认的上传目录可能与预期不符,需要显式设置。
  3. 没有错误处理机制。

修正后的代码

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();
    });
}

解释:

  1. 设置上传目录:通过 form.uploadDir 显式指定上传文件的临时存储目录。
  2. 错误处理:在 form.parse 的回调函数中增加错误处理逻辑,确保如果发生错误能够返回适当的 HTTP 状态码和错误信息。
  3. 变量使用:正确地使用 fields['filename'] 来获取前端表单提交的文件名,并将其与上传的文件关联起来。
  4. 日志记录:增加更多的日志记录来帮助调试。

通过这些改进,代码将更加健壮且易于维护,能够更好地处理实际开发环境中的各种情况。


顶,昨天试验的时候刚好遇到这个问题,还在郁闷哪里的问题,就看到楼主的解答!谢谢楼主

彼此彼此,共同学习~

已经跟进了。还跟进了《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;

不知道怎么回事

顺便问下 楼主,我安装eclipse的node调试插件后,如何配合debug的config,我的一直报错,我发表过一篇文章,不知道您是如何解决的?

自己回答下,因为我用的是window下安装node,没有源码和类库,所以导致这个问题…我试了下cygwin下 是wonderful。。。哈哈

不好意思。这几天一直有事。问题解决了 吗?这个是我iteye上的写的,你可以看一下。 http://baiyejianxin.iteye.com/admin/blogs/1401775

我当时遇到一个问题,是安装了迅雷的游戏加速器。导致LSP被修改了。导致无法访问。一直等待状态。你看看是不是也是类似的问题。至于书里面写的那段例子我测试是没有问题的。我在windows下就OK。

我觉得不是你代码的问题。我猜测是网络的问题。你用360安全卫士中–功能大全–修复网络(LSP)修复一下事实。我当初遇到的问题也是发送请求之后一直不执行代码段。修复了一下网络,一切正常了。

看到帖子都是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 文件夹存在且具有适当的权限。

回到顶部