引言:程序要做到:健壮性、低耦合、可扩展、方便程序员分工合作

上传图片值nodejs服务器并显示图片的源代码:

post.html :

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>图片上传</title>
</head>
<body>
<!--
form表单:
action 向何处发送表单数据(url)
method 方法
enctype 上传类型
--> <form action="/upload" method="post" enctype="multipart/form-data">
<!--描述-->
<input type="text" name="description">
<!--上传图片-->
<input type="file" name="myFile">
<!--提交按钮-->
<input type="submit" value="点击提交">
</form>
</body>
</html>

formidable_upload.js :

/**
* 使用插件前,需要配置环境 npm install formidable
* 扩展应用,使得上传到服务器的图片可以显示
*/
var formidable = require('formidable');
var http = require('http');
var util = require('util'); // 1.http 和 util 是nodejs的内核模块,不需要单独安装
var fs = require('fs'); // 4.引入文件模块fs // 16.创建模块,定义函数封装
function start() { // 17.调用start()方法,启动HTTP服务器
// 定义onRequest方法,接收并处理HTTP请求的
function onRequest(request, response) { // 通过http模块创建一个服务器(http服务器)
if (request.url === '/upload' && request.method.toLowerCase() === 'post') { // 对上传路径进行判断
// 针对图片上传进行处理
// 解析上传文件
var form = new formidable.IncomingForm(); form.uploadDir = "public/upload/"; // 10.设置图片上传路径
form.parse(request, function(err, fields, files) {
fs.renameSync(files.myFile.path,"tmp/test.png"); // 11.文件搬移(覆盖"tmp/test.png")
response.writeHead(200, {'content-type': 'text/html'}); // 12.响应一个页面
response.write('received image:<br/>');
response.write("<img src='/show'>"); // 13.将图片展示出来
response.end();
}); return;
} else if(request.url === '/show') { // 3.扩展应用,使得上传到服务器的图片可以显示
// 调试
console.log("request for show is received");
// 5.通过文件模块fs,将图片写入响应
fs.readFile("tmp/test.png","binary",function(error, file) {
if(error){ // 6.读取失败
response.writeHead(500, {'content-type': 'text/plain'}); // writeHead自请求头 可以写回请求头
console.log(error);
response.write('500 服务器内部错误');
response.end();
} else { // 7.读取数据成功
response.writeHead(200, {'content-type': 'image/png'}); // content-type 返回的文件格式
response.write(file,"binary"); // 将文件以二进制的方式写到页面上
response.end();
}
}); // 读取文件readFile("文件","读取方式 binary二进制",回调函数 通过回调函数进行响应) return;
} // 展示上传文件表单
var body = fs.readFileSync('./post.html');// 8.使用post.html替换掉固有的表单结构(response.end)
response.writeHead(200, {'content-type': 'text/html'});
response.write(body);
response.end();
// response.end(
// '<form action="/upload" enctype="multipart/form-data" method="post">'+
// '<input type="text" name="title"><br>'+
// '<input type="file" name="upload" multiple="multiple"><br>'+
// '<input type="submit" value="Upload">'+
// '</form>'
// );
} http.createServer(onRequest).listen(80,function(){ //15.将onRequest作为参数传到createServer()方法中
// 9.设置服务器返回信息
console.log("Server is starting on port 80.");
}); // 2.改成web默认端口 80
} exports.start = start;// 18.将start()方法暴露出去,以便外部调用

将formidable_upload.js进行优化 及 模块化开发:

index.js :

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

server.start();

server.js :

/**
* 主文件
* 使用插件前,需要配置环境 npm install formidable
* 扩展应用,使得上传到服务器的图片可以显示
*/
var http = require('http');
var url = require('url');// 20.引入url模块
var router = require('./router.js'); // 23.引入router.js // 16.创建模块,定义函数封装
function start() { // 17.调用start()方法,启动HTTP服务器
// 定义onRequest方法,接收并处理HTTP请求的
function onRequest(request, response) { // 通过http模块创建一个服务器(http服务器)
// // 方法一
// if(request.url === '/aaa'){}
// else if(request.url === '/bbb'){}
// ... // // 方法二
// switch (request.url) {
// case 'aaa':
// break;
// default:
// } // 19.方法三:定义一个函数,并暴露给其他模块调用
router.route(request, response); // 21.调用route()方法, pathname请求 response响应
} http.createServer(onRequest).listen(80,function(){ //15.将onRequest作为参数传到createServer()方法中
// 9.设置服务器返回信息
console.log("Server is starting on port 80.");
}); // 2.改成web默认端口 80
} exports.start = start;// 18.将start()方法暴露出去,以便其他模块调用

router.js :

// 文件的处理 及 第三方插件的引用 代码拆分
var util = require('util'); // 1.http 和 util 是nodejs的内核模块,不需要单独安装
var url = require('url'); // 25.引入url模块
var requestHandler = require('./requestHandler.js'); // 41.引入requestHandler.js模块
var handle = requestHandler.handle; // 42.定义handle对象,并赋值
// 20.封装route函数进行请求的处理
function route(request, response){ // 通过route进行转发、响应
// 24.将request整体引入,在route下进行统一的处理
var pathname = url.parse(request.url).pathname; // 判断需求 if(typeof(handle[pathname]) === "function"){
console.log("about to route to handle" + pathname); // 交给具体的请求程序执行
// 判读handle[pathname]的类型是方法,则执行这个方法
handle[pathname](request, response);
} else {
// 38.特殊情况处理
console.log(pathname);
response.writeHead(404, {'content-type': 'text/plain'});
response.write("404, Not Found.");
response.end();
} // if (pathname === '/upload' && request.method.toLowerCase() === 'post') { // 对上传路径进行判断
// console.log("request for upload is received. 请求已收到."); // console.log("about to route to upload Handle 路由给upload请求处理函数.");
// uploadHandler.upload(request, response); // 27.调用uploadHandler()方法 // } else if(pathname === '/show') { // 3.扩展应用,使得上传到服务器的图片可以显示
// // 调试
// console.log("request for show is received"); // console.log("about to route to show Handle 路由给show请求处理函数."); // showHandler.show(request, response);// 31.调用show()方法 // } else if(pathname === '/start') { // 33.创建上传点
// // 调试
// console.log("request for start is received"); // console.log("about to route to start Handle 路由给start请求处理函数."); // startHandler.start(request, response); // 35.调用start()方法 // } else {
// // 38.特殊情况处理
// console.log(pathname);
// response.writeHead(404, {'content-type': 'text/plain'});
// response.write("404, Not Found.");
// response.end();
// }
} exports.route = route;// 22.将route()方法暴露出去,以便其他模块调用

requestHandler.js :

/**
* 40.路由表/服务单
*/
var uploadHandler = require('./uploadHandler.js'); // 29.引入uploadHandler.js模块
var showHandler = require('./showHandler.js'); // 32.引入showHandler.js模块
var startHandler = require('./startHandler.js'); // 36.引入startHandler.js模块
// 39.通过对象取值的方式,替换掉if else
// 定义handle对象,用来保存 请求与请求处理函数 的关系
var handle = {};
handle['/upload'] = uploadHandler.upload;
handle['/show'] = showHandler.show;
handle['/start'] = startHandler.start;
handle['/'] = startHandler.start;// 根目录 exports.handle = handle;// 暴露路由表对象handle,以便其他模块调用

startHandler.js :

/**
* 上传点
*/
var fs = require('fs');// 37.引入文件模板fs
// 34.定义start(),封装具体的处理方法
function start(request, response) {
// 展示上传文件表单
var body = fs.readFileSync('./post.html');// 8.使用post.html替换掉固有的表单结构(response.end)
response.writeHead(200, {'content-type': 'text/html'});
response.write(body);
response.end();
// response.end(
// '<form action="/upload" enctype="multipart/form-data" method="post">'+
// '<input type="text" name="title"><br>'+
// '<input type="file" name="upload" multiple="multiple"><br>'+
// '<input type="submit" value="Upload">'+
// '</form>'
// );
} exports.start = start;// 将start()方法暴露出去,以便其他模块调用

uploadHandler.js :

/**
* 28.单独拿出,专门用来处理图片上传请求
*/
var formidable = require('formidable');
var fs = require('fs'); // 4.引入文件模块fs
// 26.定义uploadHandler,封装具体的处理方法
function upload(request, response) {
// 针对图片上传进行处理
// 解析上传文件
var form = new formidable.IncomingForm(); form.uploadDir = "public/upload/"; // 10.设置图片上传路径
form.parse(request, function(err, fields, files) {
fs.renameSync(files.myFile.path,"tmp/test.png"); // 11.文件搬移(覆盖"tmp/test.png")
response.writeHead(200, {'content-type': 'text/html'}); // 12.响应一个页面
response.write('received image:<br/>');
response.write("<img src='/show'>"); // 13.将图片展示出来
response.end();
});
return;
} exports.upload = upload;// 29.upload()方法暴露出去,以便其他模块调用

showHandler.js :

/**
* 单独取出,专门用于图片展示
*/
var fs = require('fs');// 32.引入文件模板fs
// 30.定义show()方法,封装图片展示的具体实现方法
function show(request, response) {
// 5.通过文件模块fs,将图片写入响应
fs.readFile("tmp/test.png","binary",function(error, file) {
if(error){ // 6.读取失败
response.writeHead(500, {'content-type': 'text/plain'}); // writeHead自请求头 可以写回请求头
console.log(error);
response.write('500 服务器内部错误');
response.end();
} else { // 7.读取数据成功
response.writeHead(200, {'content-type': 'image/png'}); // content-type 返回的文件格式
response.write(file,"binary"); // 将文件以二进制的方式写到页面上
response.end();
}
}); // 读取文件readFile("文件","读取方式 binary二进制",回调函数 通过回调函数进行响应)
return;
} exports.show = show;// 将show()方法暴露出去,以便其他模块调用

.

formidable 模块化开发 代码拆分(解耦) nodejs图片服务器架构的更多相关文章

  1. Windows平台网站图片服务器架构的演进[转]

    构建在Windows平台之上的网站,往往会被业内众多架构师认为很“保守”.很大部分原因,是由于微软技术体系的封闭和部分技术人员的短视造成 的.由于长期缺乏开源支持,所以只能“闭门造车”,这样很容易形成 ...

  2. Windows平台网站图片服务器架构的演进

    在主流的Web站点中,图片往往是不可或缺的页面元素,尤其在大型网站中,几乎都将面临“海量图片资源”的存储.访问等相关技术问题.在针对图片服务器的架构扩展中,也会历经很多曲折甚至是血泪教训(尤其是早期规 ...

  3. 前端模块化开发篇之grunt&webpack篇

    几个月前写了一篇有关gulp和browserify来做前端构建的博客,因为browserify用来做js的打包时可能有些麻烦(特别是在写React的时候),所以这里再强烈推荐一款js打包工具-webp ...

  4. nginx+ftp搭建图片服务器(Windows Server服务器环境下)

    几种图片服务器的对比 1.直接使用ftp服务器,访问图片路径为 ftp://账户:密码@192.168.0.106/31275-105.jpg 不采用这种方式,不安全容易暴露ftp账户信息 2.直接使 ...

  5. Javascript模块化开发,使用模块化脚本加载工具RequireJS,提高你代码的速度和质量。

    随着前端JavaScript代码越来越重,如何组织JavaScript代码变得非常重要,好的组织方式,可以让别人和自己很好的理解代码,也便于维护和测试.模块化是一种非常好的代码组织方式,本文试着对Ja ...

  6. Js模块化开发的理解

    Js模块化开发的理解 模块化是一个语言发展的必经之路,其能够帮助开发者拆分和组织代码,随着前端技术的发展,前端编写的代码量也越来越大,就需要对代码有很好的管理,而模块化能够帮助开发者解决命名冲突.管理 ...

  7. Android模块化开发实践

    一.前言 随着业务的快速发展,现在的互联网App越来越大,为了提高团队开发效率,模块化开发已经成为主流的开发模式.正好最近完成了vivo官网App业务模块化改造的工作,所以本文就对模块化开发模式进行一 ...

  8. iOS关于模块化开发解决方案(纯干货)

    关于iOS模块化开发解决方案网上也有一些介绍,但真正落实在在具体的实例却很少看到,计划编写系统文章来介绍关于我对模块化解决方案的理解,里面会有包含到一些关于解耦.路由.封装.私有Pod管理等内容:并编 ...

  9. Angular 结合RequireJs实现模块化开发

    angular的指令是模块化很好的一个体现,下面我将只使用指令(不用控制器),结合requirejs,实现模块化开发. 模块化关系图:

随机推荐

  1. mysql 如何提高批量导入的速度

    mysql 如何提高批量导入的速度 最近一个项目测试,有几个mysql数据库的表数据记录达到了几十万条,在搭建测试环境 导入 测试数据时,十分慢.在网上搜索了一下,有下面一些方法可以加快mysql数据 ...

  2. Eclipse,myeclipse安装 配置Maven

    本文转自http://www.cnblogs.com/timeng/archive/2013/05/07/maven_install.html myeclipse自带了maven插件,但是和原生插件还 ...

  3. Android Studio查看类中所有方法和属性

    ctrl+f3效果: alt+7效果: 注意区别:虽然所有方法都有,但是顺序自己一看效果便知.一个是根据类中的顺序,另一个是根据a-z的开头字母顺序. 百度查了一下快捷键是ctrl+f12.但是自己试 ...

  4. [BZOJ2005][Noi2010]能量采集 容斥+数论

    2005: [Noi2010]能量采集 Time Limit: 10 Sec  Memory Limit: 552 MBSubmit: 4394  Solved: 2624[Submit][Statu ...

  5. (一)mysql基础和安装mysql5.7

    (1)数据库系统 RDS:关系型,oracle,mysql,mariaDB,percona server ,DB2 NoSQL:Redis,MongoDB,memcache (2)SQL语言:结构化查 ...

  6. poj1789 最小生成树

    题目连接:http://poj.org/problem?id=1789 Description Advanced Cargo Movement, Ltd. uses trucks of differe ...

  7. CF 834B The Festive Evening【差分+字符串处理】

    B. The Festive Evening time limit per test1 second memory limit per test256 megabytes inputstandard ...

  8. 洛谷 P3371 【模板】单源最短路径 【链式前向星+SPFA】

    题目描述 如题,给出一个有向图,请输出从某一点出发到所有点的最短路径长度. 输入输出格式 输入格式: 第一行包含三个整数N.M.S,分别表示点的个数.有向边的个数.出发点的编号. 接下来M行每行包含三 ...

  9. 训练指南 UVA - 11419(二分图最小覆盖数)

    layout: post title: 训练指南 UVA - 11419(二分图最小覆盖数) author: "luowentaoaa" catalog: true mathjax ...

  10. SQL Loader with utf8

    alter this line in your control file characterset UTF8 to this characterset UTF8 length semantics ch ...