1. 程式人生 > >《Node入門》學習筆記

《Node入門》學習筆記

圖書地址:《node入門》

實現檔案上傳功能

1、/start頁面實現圖片上傳,點選按鈕跳轉到/upload
2、/upload頁面處理圖片,把圖片重新命名並重新放置到./tmp/test.png,展示/show
3、/show頁面展示./tmp/test.png


有些程式碼註釋是因為之前實現的是上傳文字功能,且沒有使用formidable外掛,所以自己處理資料包。
後面的圖片上傳功能使用了外掛。

1、入口檔案index.js,負責集合各個路徑的handle方法,並把集合後的物件傳遞給伺服器。

var server = require('./server'
); var router = require('./router'); var requestHandlers = require('./requestHandlers'); /* 每一個js檔案對應一個路徑的處理方法,通過模組引入後放到handle物件中 將需要用的handle物件與路由處理函式傳給伺服器啟動模組 */ var handle = { '/': requestHandlers.start, '/start': requestHandlers.start, '/upload': requestHandlers.upload, '/show': requestHandlers.
show }; server.start(router.route, handle);

2、建立一個伺服器啟動模組server.js,把接收到的request與需要返回的response初始化,並傳遞給路由模組router.js

// server.js
var http = require('http');
var url = require('url');
/*
    接收到路由處理方法route和handle處理方法
    將接收到的request中的pathname傳給路由處理方法route
    將handle也傳給route,使得route通過handle處理pathname
    將接收到的response也傳給route,交由handle來處理(非阻塞)
    將整個request都傳遞給route,方便獲取資料
*/
function start(route, handle){ function onRequest (request, response) { // var postData = ''; var pathname = url.parse(request.url).pathname; console.log("Request for " + pathname + " received."); // request.setEncoding("utf8"); //為了使整個過程非阻塞,Node.js會將POST資料拆分成很多小的資料塊 // request.addListener("data", function (postDataChunk) { // postData += postDataChunk; // console.log("Received POST dara chunk '" + postDataChunk + "'."); // }) // request.addListener('end', function () { // route(handle, pathname, response, postData); // }) route(handle, pathname, response, request); } http.createServer(onRequest).listen(8888); console.log('Server has started!'); } module.exports.start = start;

3、路由處理模組router.js

/*
    接收到pathname和handle,判斷在handle中是否有pathname的處理方法。
    有的話就處理,沒有的話就輸出提示。
    其他引數只是通過router傳遞給handle處理。
*/
function route(handle, pathname, response, request) {
    console.log('About to route a request for '+ pathname);
    if(typeof handle[pathname]==='function') {
        handle[pathname](response, request);
    }else {
        console.log('No request handler found for '+ pathname);
        response.writeHead(404, {"Content-Type": "text/plain"});
        response.write("404 Not found");
        response.end();
    }
}

module.exports.route = route;

4、handle處理方法模組requestHandlers.js,其實應該是一個處理方法一個檔案的,但是這個專案功能比較少,所以都放在一個檔案裡了。

var exec = require('child_process').exec; //執行shell命令
var querystring = require('querystring'),
    fs = require('fs'),
    formidable = require("formidable");

function sleep(milliSeconds){
    var startTime = new Date().getTime();
    while(new Date().getTime() < startTime + milliSeconds);
}
function start(response, request) {
    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" enctype="multipart/form-data" method="post">'+
        '<input type="file" name="upload" />'+
        '<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';
    console.log('about to parse');
    form.parse(request, function (error, fields, files) {
        console.log('parsing done');
        fs.renameSync(files.upload.path, './tmp/test.png');
        response.writeHead(200, {
            'Content-Type': 'text/html'
        });
        response.write('received image: <br/>');
        response.write('<img src="/show">');
        response.end();
    })
    // response.writeHead(200, {
    //     "Content-Type": "text/plain",
    //
    // });
    // response.write("You've sent: " + querystring.parse(postData).text);
    // response.end();
}
function show(response, request) {
    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();
        }
    })
}
module.exports.start = start;
module.exports.upload = upload;
module.exports.show = show;

我自己的專案原始碼地址:

nodejs-test-uploadFile