zoukankan      html  css  js  c++  java
  • formidable 模块化开发 代码拆分(解耦) nodejs图片服务器架构

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

    上传图片值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()方法暴露出去,以便其他模块调用
    

    .

  • 相关阅读:
    黄金点游戏(结对项目)
    WORD COUNT
    企业级应用与互联网应用的区别
    问题
    软件工程期末学习总结
    自我介绍
    四则运算程序
    个人自评
    contenttype
    ubuntusaltstack
  • 原文地址:https://www.cnblogs.com/crazycode2/p/7076145.html
Copyright © 2011-2022 走看看