目的:使用Node.js实现文件上传并将上传的文件显示到浏览器中

基本工具:Node.js,在windows下需要下载cygwin64来运行shell命令

文件:服务器模块、请求路由模块、请求处理程序模块、index.js入口文件

步骤:在目录中创建server.js、router.js、requestHandlers、index.js这文件,分别代表以上几个文件。

  步骤一:在index.js文件中使用require引入以上模块,

const server = require('./server');
const router = require('./router');
const requestHandlers = require('./requestHandlers');

  接着在index.js文件中需要定义路由,我们首先定义一个handle对象,用于保存路由,然后对应请求处理程序模块中的提供的方法(还没写)

//定义路由
let handle = {};
handle['/'] = requestHandlers.start;
handle['/start'] = requestHandlers.start;
handle['/upload'] = requestHandlers.upload;
handle['/show'] = requestHandlers.show;

  最后调用引入的服务器模块提供的方法server.start();并传入两个参数,第一个参数是请求路由模块提供的路径方法router.route,第二个参数是用于定义路由的handle对象

server.start(router.route,handle);

  index.js文件的代码如上

  步骤二:在请求处理程序模块requestHandlers.js文件中,我们需要引入fs模块用于读取文件,formidable模块用于格式化上传的表单

const fs = require('fs');
const formidable = require('formidable');

  接着我们来完善之前在index,js文件中对应的方法,在requestHandlers.js文件中,接着写下exports.start方法,这个方法接收一个参数res,届时将在服务器模块中传入该响应参数  

exports.start = (res)=>{//服务器传入的响应参数
console.log("Request handler 'start' was called.");
res.writeHead(200, {"Content-Type": "text/html"});//告诉浏览器文件格式
let 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="上传文件" />'+
'</form>'+
'</body>'+
'</html>';
res.end(body);//响应浏览器,并将body参数传进入
};
exports.upload = (res,req)=>{//对上传的文件进行处理
console.log("Request handler 'upload' was called.");
let form = new formidable.IncomingForm();
//对上传的文件进行处理
console.log('对上传的文件进行处理');
form.parse(req,(err,fields,files)=>{
//上传的文件处理完毕
console.log('上传的文件处理完毕');
console.log(files.upload.path);
fs.renameSync(files.upload.path,"/tmp/test.png");//将路径一的文件保存到路径二
res.writeHead(200,{"Content-Type":"text/html"});
res.end("接收到的图片:</br><img src='/show/'>"); }); // res.writeHead(200, {"Content-Type": "text/plain"});
// res.end("You've sent: " + querystring.parse(postData).text);//使用querystring模块获取上传数据中的文本信息
};
exports.show = (res)=>{//从文件中读取数据并显示到页面
console.log('在页面中显示上传数据的请求已被调用');
fs.readFile("/img/test.png","binary",(err,file)=>{
if(err){
res.writeHead(500,{"Content-Type":"text/plain"});
res.end(err+'\n');
}else {
res.writeHead(200,{"Content-Type":"image/png"});
res.write(file,"binary");
res.end();
}
});
};

即对应的处理程序做对应的事情

步骤三:在server文件中,引入url模块用于解析地址,获取当前路径,

const url = require('url');

接着创建一个对外提供的start方法,并接收两个参数,route和handle,分别用于处理请求路由和路由对象,在该文件中我们还通过url模块提供的parse().pathname获取到了路径地址,然后调用参数传进来的请求路由方法,并传入路由对象、当前路径、接收到的请求req、响应浏览器的res,最后监听端口

exports.start = (route,handle)=>{
require('http').createServer((req,res)=>{
const pathname = url.parse(req.url).pathname;//获取当前路径
route(handle,pathname,res,req);
console.log('路径名称:'+pathname); }).listen(8888);//监听8888端口
};

步骤四:在router文件中,我们定义一个函数用于该模块提供对外的接口,该函数接收四个参数,路由对象、当前路径、接收到的请求req、响应浏览器的res,在函数中判断当前路径在路由对象中是否存在该函数,如果存在则调用该方法,并传入接收到的请求req、响应浏览器的res两个参数,否则告诉浏览404,页面未找到

exports.route = (handle,pathname,res,req)=>{
console.log("路径名称 " + pathname);
if(typeof handle[pathname] === 'function'){//匹配是否有这个请求处理程序
return handle[pathname](res,req);
}else{
console.log("No request handler found for " + pathname);
res.writeHead(404, {"Content-Type": "text/plain"});
res.end("404 Not found");
}
};

总体思路:

要把服务器、路由、请求处理程序分开,最后用index.js文件全部连在一起;

①首先创建单独的服务器处理模块,在模块里面创建一个服务器,并通过请求参数和url模块获取到当前的路径,接着调用一个路径处理函数,这个函数传四个参数,第一个参数是从index.js传入的请求处理函数的一个集合对象,第二个参数是当前路径,第三个参数是req,第四个参数是res,最后监听端口,并将这些代码作为一个函数对外开放以方便index.js引入,并且该函数接受两个参数,第一个参数是路径处理函数,第二个参数是请求处理程序函数的对象,服务器模块完成;

②然后创建路径处理模块,该模块将作为一个函数对外开放,函数接收四个参数,第一个参数是从服务器模块传入的请求处理函数的一个集合对象,第二个参数是从服务器模块传入的路径,第三个参数是req,第四个参数是res,然后进行if判断,将从服务器模块传入的路径作为请求处理函数的一个集合对象的参数,判断是否是function,如果是则调用该请求处理程序并传入req,res;

③接着创建请求处理程序,该模块创建不同的对外开放函数,函数参数接收req,res,根据需求制定不同的请求处理程序;

④最后创建一个index.js文件,该文件引入服务器模块,路径处理模块,请求处理程序模块,接着创建一个空对象,把希望制定的路由作为对象的参数然后将对应的请求处理程序模块对应的程序赋值给该参数,最后调用服务器模块对外开放的函数,并传入两个参数,第一个参数是路径处理模块对外的函数,和新创建的的请求处理函数的集合对象。

源教程自:https://www.nodebeginner.org/index-zh-cn.html

Node.js入门-知识整理的更多相关文章

  1. 让我们一起学习《Node.js入门》一书吧!

    Node.js入门 读完本书之后,你将完成一个完整的web应用,该应用允许用户浏览页面以及上传文件. 里面对一些知识的讲解,让你略窥Node.js的门径.最好一段代码一段代码的写下来,我的习惯是手里拿 ...

  2. Node.js基础知识

    Node.js入门   Node.js     Node.js是一套用来编写高性能网络服务器的JavaScript工具包,一系列的变化由此开始.比较独特的是,Node.js会假设在POSIX环境下运行 ...

  3. 极简 Node.js 入门 - Node.js 是什么、性能有优势?

    极简 Node.js 入门系列教程:https://www.yuque.com/sunluyong/node 本文更佳阅读体验:https://www.yuque.com/sunluyong/node ...

  4. 极简 Node.js 入门 - 3.2 文件读取

    极简 Node.js 入门系列教程:https://www.yuque.com/sunluyong/node 本文更佳阅读体验:https://www.yuque.com/sunluyong/node ...

  5. 极简 Node.js 入门 - 4.3 可读流

    极简 Node.js 入门系列教程:https://www.yuque.com/sunluyong/node 本文更佳阅读体验:https://www.yuque.com/sunluyong/node ...

  6. 极简 Node.js 入门 - 4.4 可写流

    极简 Node.js 入门系列教程:https://www.yuque.com/sunluyong/node 本文更佳阅读体验:https://www.yuque.com/sunluyong/node ...

  7. 极简 Node.js 入门 - 5.1 创建 HTTP 服务器

    极简 Node.js 入门系列教程:https://www.yuque.com/sunluyong/node 本文更佳阅读体验:https://www.yuque.com/sunluyong/node ...

  8. 极简 Node.js 入门 - 5.3 静态资源服务器

    极简 Node.js 入门系列教程:https://www.yuque.com/sunluyong/node 本文更佳阅读体验:https://www.yuque.com/sunluyong/node ...

  9. Node.js 入门手册:那些最流行的 Web 开发框架

    这篇文章与大家分享最流行的 Node.js Web 开发框架.Node 是一个服务器端 JavaScript 解释器,它将改变服务器应该如何工作的概念.它的目标是帮助程序员构建高度可伸缩的应用程序,编 ...

随机推荐

  1. bzoj1179 Atm

    Description Input 第一行包含两个整数N.M.N表示路口的个数,M表示道路条数.接下来M行,每行两个整数,这两个整数都在1到N之间,第i+1行的两个整数表示第i条道路的起点和终点的路口 ...

  2. django2.0基础

    一.安装与项目的创建 1.安装 pip install django 2.查看版本 python -m django --version 3.创建项目 django-admin startprojec ...

  3. Python发送邮件(带附件的)

    有时候做自动化测试任务,任务完成后,需要将结果自动发送一封邮件,这里用到smtplib模块,直接导入就行,这里以163邮箱为例,需要用到授权码,我用类写一下: 如果是发送qq邮箱,要将smtp 改成s ...

  4. Kafka Connect HDFS

    概述 Kafka 的数据如何传输到HDFS?如果仔细思考,会发现这个问题并不简单. 不妨先想一下这两个问题? 1)为什么要将Kafka的数据传输到HDFS上? 2)为什么不直接写HDFS而要通过Kaf ...

  5. Python小技巧整理

    一.python小工具: 1.内置下载和网站: 进入相应目录:2.x python -m SimpleHTTPServer 3.x python -m http.server 2.字符串转换为JSON ...

  6. 使用UITextView的dataDetectorTypes实现超链接需要注意的事项!

    项目中需要在UITextView上识别URL,手机号码.邮箱地址等等信息.那么就用到了它的dataDetectorTypes属性.我的UITextView加在UITableViewCell上面的,当单 ...

  7. 洛谷3067 BZOJ 2679题解(折半搜索)

    传送门 BZOJ传送门(权限题) 看到n小于20,就可以想到搜索 所有的数要么在集合a中,要么在集合b中,要么都不在 可是3^n复杂度会炸,我们考虑优化 可以利用折半搜索,将前面一半的所有可能情况与后 ...

  8. 微服务开源生态报告 No.2

    通常,我们都会通过在 GitHub 上订阅邮件列表,来了解社区动态.这一次,我们联合以上各开源项目的负责人,发布「微服务开源生态报告」,汇集各个开源项目近期的社区动态,帮助开发者们更高效的了解到各开源 ...

  9. 2019.8.3 [HZOI]NOIP模拟测试12 A. 斐波那契(fibonacci)

    2019.8.3 [HZOI]NOIP模拟测试12 A. 斐波那契(fibonacci) 全场比赛题解:https://pan.baidu.com/s/1eSAMuXk 找规律 找两个节点的lca,需 ...

  10. Flask学习之二 模板

    继续学习flask 本部分Miguel Grinberg教程的翻译地址:http://www.pythondoc.com/flask-mega-tutorial/templates.html 英文原文 ...