使用node构建web应用

  1. 文件结构

    tmp
    index.js              => 应用主文件
    requestHandlers.js    => API处理
    router.js             => 路由处理
    server.js             => 服务器
    
  2. 构建服务器模块 server.js

    const http = require('http')   // 调用 http 模块,用于启动一个服务器
    const url = require('url')     // 调用 url 模块,用于处理链接
    
    function start(route, handle) {
        
      function onRequest(request, response) {
        const pathname = url.parse(request.url).pathname
        // 解析请求体中的url,获取pathname
        route(handle,pathname,response,request)
        // 调用函数 route
      }
        
      http.createServer(onRequest).listen(8888)
      // 创建一个监听 8888 端口的 http.Server 实例,并为 request 事件绑定 onRequest 回调函数
    }
    
    exports.start = start
    // 导出函数
    
  3. 构建路由处理主模块 router.js

    function route(handle, pathname,response,request){
      if(typeof handle[pathname] === 'function'){
        // 如果路由存在,则调用相应的处理函数
        handle[pathname](response,request)
      }else{
        // 如果路由不存在,则直接返回相应提示
        response.writeHead(404,{"Content-Type":"text/plain"});
        response.write("404 Not found");
        response.end();
      }
    }
    
    exports.route = route
    
  4. 构建路由处理函数模块 routerHandle.js

    这里,只封装五个路由的处理函数,分别是:

    • /start => 主页面路由
    • /uploadupload => 主页面中上传图片的 POST 请求
    • /viewview => 请求预览上传的图片的
    • /writewrite => 主页面中填写文本的 GET
    • /texttext => 预览填写的文本
    const querystring = require("querystring")  // 解析 postData 模块
    const fs = require("fs")                    // 读取文件模块
    const formidable = require("formidable")    // 文件上传模块, formidable 插件需要安装
    
    function start(response){  // 返回一个 html 页面
      console.log('one')
      const 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="Submit text" />'+
        '</form>'+
        '</body>'+
        '</html>';
    
        response.writeHead(200,{"Content-Type":"text/html"});
        response.write(body);
        response.end();
    }
    
    function upload(response, request){ // 上传
      const form = new formidable.IncomingForm()
      form.uploadDir='tmp'
      form.parse(request,(error, fields, files)=>{ // 解析文件
        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' style='width: 300px' />") // 返回信息
        response.end()
      })
    }
    
    function show(response, postData){ // 预览
      fs.readFile("./tmp/test.png", "binary", (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()
        }
      })
    }
    
    exports.start = start
    exports.upload = upload
    exports.show = show
    
  5. 构建应用主文件 index.js

    const server = require('./server')  // 导入 server.js 模块
    const router = require('./router')  // 导入 router.js 模块
    const routerHandle = require('./routerHandle')  // 导入 routerHandle.js 模块
    const handle = {}
    handle['/'] = routerHandle.start
    handle['/start'] = routerHandle.start
    handle['/upload'] = routerHandle.upload
    handle['/show'] = routerHandle.show
    server.start(router.route, handle)  // 开始服务器