Android APP的开发告一段落,一个稳定的、实现了基本功能的APP已经交付用户使用了!我和老板交流了下,接下来准备转战Node.js了,而且一部分前端的功能也要做进去!哈哈哈~~~接下来要朝一个全(zuo)栈(si)工程师进发了,想想都有点小激动呢!这几天一直在学新东西,HTML CSS JavaScript jQuery SQL bootstrap Node.js ···········
  
  (好吧,看着这么多前端+后端的知识,我已经凌乱在风中了-。-·····)
  
  要学的东西是蛮多的,时间又紧,后来我在知乎一番搜索后决定主攻Node.js,SQL等用到时再去查语句怎么写,JavaScript学习基本的语法和关键的一些思想(回调、闭包····)HTML CSS 力求能看懂,jQuery也尝试着写,这里先给大家推荐一个不错的网站,世界上最大学习网站开发的地方 w3schools (简单直白的英文网站,可以锻炼下自己看英文文档的能力,貌似需要FQ,请自备梯子),没有梯子的童鞋可以去 菜鸟教程(中国人自己翻译的网站,内容基本一致),小小的吐槽下:w3schools 的exercise太水了,几道题基本做法都差不多,最多就修改两三个地方,并且学完之后的测试居然就是24道选择题(很多还都是判断题······),还以为很难呢·······不过貌似人家盈利的方式就是最后学完后的certificate,价格是惊人的 95 美刀(在国外知识确实很值钱-。-)
  
  废话不多说,进入正题吧,我是在网上看的这本《Node入门》总共就42页,一边看一边背书里的代码自己写,一天就看完了,还是有不少收获的。
  
  首先咱们要安装Node.js,我用的是Windows版本的安装包,直接下载安装就好,然后大家还需要装一下sublime text 3。下面是我们最终要达到的三个目标。
  
  用户可以通过浏览器使用我们的应用。
  
  当用户请求http://127.0.0.1:8888/start时,可以看到一个欢迎页面,页面上有一个文件上传的表单。
  
  用户可以选择一个图片并提交表单,随后文件将被上传到http://127.0.0.1:8888/upload,该页面完成上传后会把图片显示在页面上。
  
  最后的效果是这样:上传图片的效果
  
  图片上传后的效果
  
  书里有一部分关于直接把函数作为参数进行传值的话我觉得讲的很好,现在摘录出来方便大家理解下什么是 函数式编程
  
  行为驱动执行
  
  请允许我再次脱离主题,在这里谈一谈函数式编程。
  
  将函数作为参数传递并不仅仅出于技术上的考量。对软件设计来说,这其实是个哲学问题。想想这样的场景:在index文件中,我们可以将router对象传递进去,服务器随后可以调用这个对象的route函数。
  
  就像这样,我们传递一个东西,然后服务器利用这个东西来完成一些事。嗨那个叫路由的东西,能帮我把这个路由一下吗?
  
  但是服务器其实不需要这样的东西。它只需要把事情做完就行,其实为了把事情做完,你根本不需要东西,你需要的是动作。也就是说,你不需要名词,你需要动词。
  
  理解了这个概念里最核心、最基本的思想转换后,我自然而然地理解了函数编程。
  
  关于Node.js还有一点需要理解的是阻塞IO与非阻塞IO(使用回调函数)的不同
  
  简单来说,假设我们要去快餐店吃饭,有两种不同服务模式的快餐店,一种是基于事件驱动的(我们的node服务器),一种不是(像iis,apache)。对于传统的服务器,在接收到你的请求之后,直到他完成你的请求,否则他不会去接待下一个用户。当服务员输入你的订单之后还有很多事情要做,处理你的支付,帮你倒水,还有一段时间(不确定时长)去等待厨房准备好你的汉堡。服务员(相当于服务器上的线程)每次只能接待一位顾客,直到完成当前顾客的接待之后,才会去接待下一位顾客。很显然,这种方式效率不高,他浪费了太多的时间在等待厨房做汉堡的工作上。而现实中的快餐店采用的是另外一种模式,当接收到你的订单之后,他会给你一个号码牌,这个号码牌就相当于回调函数。接着他会去接待下一位顾客。当你的订餐准备好之后,服务员会呼叫你的号码叫你来取餐。这就是node采用的模式,看得出他要高效的多。
  
  一路看着书往下写,我们把这个小Node.js程序分成了三个主要的模块:server(服务器)、router(分发处理不同的请求)、requestHandle(真正处理请求的部分),剩下的就是细节的完善。
  
  最后贴上全部的源码来供大家学习吧,windows下有一个坑,那个坑花了我两个小时才找到,具体见代码·····
  
  主页文件index.js
  
  var server = require('./server'); //本地写的server.js 文件
  
  var router = require('./router');
  
  var requestHandle = require('./requestHandle');
  
  var handle = {};
  
  handle["/"] = requestHandle.start;
  
  handle['/start'] = requestHandle.start;
  
  handle['/upload'] = requestHandle.upload;
  
  handle['/directory'] = requestHandle.directory;
  
  handle['/display'] = requestHandle.display;
  
  server.start(router.route,handle);
  
  server.js
  
  //调用node.js的自带模块http,并将其返回值赋值给 var http
  
  var http = require("http");
  
  var url = require("url");
  
  function start(route, handle) {
  
  //用onRequest作为回调函数
  
  function onRequest(request, response) {
  
  var pathName = url.parse(request.url).pathname;
  
  var postDate = "";
  
  console.log("Request for " + pathName + " has received.");
  
  route(pathName,handle,response,request);
  
  };
  
  http.createServer(onRequest).listen(8888);
  
  console.log("server www.hjha178.com has start");
  
  }
  
  exports.start = start;
  
  router.js
  
  function route(pathName,handle,response,request){
  
  console.log("start router with handle and path name is " + pathName);
  
  if (typeof handle[pathName] === "function") www.furggw.com{
  
  return handle[pathName](response,request); //Node.js中这个执行的方法太酷了
  
  }else{
  
  console.log("404 not find "www.dashugw.com);
  
  response.writeHead(404,{"Content-Type":"text/plain"});
  
  response.write("404 not found");
  
  response.end();
  
  }
  
  }
  
  exports.route = route;
  
  requestHandle.js
  
  var exec = require('child_process').exec;
  
  var queryString = require('querystring');
  
  var fs = require('fs'www.567860.cn);
  
  var formidable = require('formidable');
  
  function start(response) {
  
  console.log("handler 'start' www.272345.cn was called");
  
  //仅仅是为了学习才这么把html写这里的,实际中是绝不能这么丑陋地把html直接写在处理程序里的
  
  var body = '<html>' +
  
  '<head>' +
  
  '<meta http-equiv="content-type" content="text/html;charset=UTF-8">' +
  
  '</head>' +
  
  '<body>' +
  
  //定义submit后的跳转的url是/upload,且是一个post请求
  
  '<form action="/upload" method="post" enctype = "multipart/form-data">' +
  
  '<input type="file" name="upload" multiple="multiple" ><br/>' +
  
  '<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("handler 'upload' was called");
  
  var form = new formidable.IncomingForm();
  
  //关键:这里需要改变form的默认的上传路径,且在windows下由于权限的问题,需要手动创建tmp文件夹
  
  form.uploadDir = 'tmp';
  
  form.parse(request, www.taohuayuan178.com function(error, fields, files) {
  
  console.log(files.upload.path);
  
  // fs.renameSync(files.upload.path, "/tmp/test.png");
  
  //考虑到这个是Sync同步操作,则必须对异常进行捕获,Node.js不推荐同步操作
  
  try{
  
  fs.renameSync(files.upload.path,'tmp/test.png');
  
  }catch(e){
  
  console.log(e);
  
  }
  
  response.writeHead(200, {
  
  "Content-Type": "text/html"
  
  });
  
  response.write('<img src="/display"/>');
  
  response.end();
  
  });
  
  }
  
  function display(response) {
  
  console.log("handler 'display' was called");
  
  fs.readFile("tmp/test.png",function(error, file) {
  
  if (error) {
  
  console.log("sorry");
  
  } else {
  
  response.writeHead(200,{"Content-Type":"image/png"});
  
  // response.write(data);
  
  response.write(file);
  
  response.end();
  
  };
  
  });
  
  }
  
  /*//响应用户输入的display方法
  
  function display(response,postDate) {
  
  console.log("handler 'display' was called");
  
  response.writeHead(200, {
  
  "Content-Type": "text/plain"
  
  });
  
  response.write("You input " + queryString.parse(postDate).text);
  
  response.end();
  
  }*/
  
  exports.start = start;
  
  exports.upload = upload;
  
  exports.directory = directory;

《Node入门》读书笔记——用Node.js开发一个小应用的更多相关文章

  1. [整理]Node入门 » 一本全面的Node.js教程 - Demo实践所遇到的问题

    花了一个上午看完[转载]Node入门 » 一本全面的Node.js教程 根据里面的Demo自己手动实现过程中还是遇到了些问题,特整理在此. <1>.由于node.msi安装包已经自动添加了 ...

  2. 第三章 Git的入门 - 读书笔记

    Android驱动月考3 第三章 Git的入门 - 读书笔记 对于Github,这是全世界最大的开源平台,你可以把你做的项目在这里开源,把你发现的一些新技术在这里开源,向全世界的开发者们分享,大家都彼 ...

  3. 【转】利用 three.js 开发微信小游戏的尝试

    前言 这是一次利用 three.js 开发微信小游戏的尝试,并不能算作是教程,只能算是一篇笔记吧. 微信 WeChat 6.6.1 开始引入了微信小游戏,初期上线了一批质量相当不错的小游戏.我在查阅各 ...

  4. 用Vue.js开发微信小程序:开源框架mpvue解析

    前言 mpvue 是一款使用 Vue.js 开发微信小程序的前端框架.使用此框架,开发者将得到完整的 Vue.js 开发体验,同时为 H5 和小程序提供了代码复用的能力.如果想将 H5 项目改造为小程 ...

  5. MPVUE - 使用vue.js开发微信小程序

    MPVUE - 使用vue.js开发微信小程序 什么是mpvue? mpvue 是美团点评前端团队开源的一款使用 Vue.js 开发微信小程序的前端框架.框架提供了完整的 Vue.js 开发体验,开发 ...

  6. js实现一个小游戏(飞翔的jj)

    js实现一个小游戏(飞翔的jj) 源代码+素材图片在我的仓库 <!DOCTYPE html> <html lang="en"> <head> & ...

  7. 读书笔记: 深入浅出node.js

    >> 深入浅出node.js node.js是c++编写的js运行环境 浏览器: 渲染引擎 + js引擎 后端的js运行环境 node.js用google v8引擎,同时提供很多系统级的A ...

  8. [转载]Node入门 » 一本全面的Node.js教程

    http://www.nodebeginner.org/index-zh-cn.html 作者: Manuel Kiessling 翻译: goddyzhao & GrayZhang & ...

  9. node入门(二)——gulpfile.js初探

    本文关于gulpfile.js怎么写,利于完成个性化需求.本文开发环境默认已安装node,详情参考<node入门(一)——安装>. 一.安装gulp npm install -g gulp ...

随机推荐

  1. log4j 注意事项

    因为项目是 ssm+maven 所以有关log4j的注意事项记录一下 首先,需要在web.xml里配置spring的拦截器用于支持在项目下生成log4j日志文件 <!-- 配置log4j输出日志 ...

  2. scala : 类型与类

    scala类型系统:1) 类型与类 在Java里,一直到jdk1.5之前,我们说一个对象的类型(type),都与它的class是一一映射的,通过获取它们的class对象,比如 String.class ...

  3. 关于js回调方法 js递归时使用方法

    js中递归调用本身可以这样: function a1(n){ a1(n)}但是如果需要在参数n进行自增的情况下判断会出错: function a1(n){ if(n>10) return 'aa ...

  4. ython进阶06 循环对象

    这一讲的主要目的是为了大家在读Python程序的时候对循环对象有一个基本概念. 循环对象的并不是随着Python的诞生就存在的,但它的发展迅速,特别是Python 3x的时代,循环对象正在成为循环的标 ...

  5. vue2.0做移动端开发用到的相关插件和经验总结

    最近一直在做移动端微信公众号项目的开发,也是我首次用vue来开发移动端项目,前期积累的移动端开发经验较少.经过这个项目的锻炼,加深了对vue相关知识点的理解和运用,同时,在项目中所涉及到的微信api( ...

  6. fetch上传文件报错的问题(multipart: NextPart: EOF)

    技术栈 后台: gin(golang) 前端: react+antd+dva 问题 前端这边使用fetch发送http请求的时候,后端解析formData报错: multipart: NextPart ...

  7. kNN--近邻算法

    kNN--近邻算法 kNN算法的核心思想是如果一个样本在特征空间中的k个最相邻的样本中的大多数属于某一个类别,则该样本也属于这个类别,并具有这个类别上样本的特性. 在机器学习中常用于分类. 数学内容: ...

  8. 剑指 Offer——和为 S 的连续正数序列

    1. 题目 2. 解答 定义两个指针,刚开始分别指向 1 和 2,求出位于这两个指针之间的元素和.如果和大于 S,前面的指针向后移直到和不大于 S 为止:反之,如果和等于 S,则此时两个指针之间的元素 ...

  9. loadrunner处理https请求

    录制到的脚本如下: login() { lr_think_time(10); web_url("verifycode.jsp", "URL=https://192.168 ...

  10. Phonegap 环境配置

    目前要开发 Web App 还是有比较多的选择的 如 Phonegap.MUI.AppCan,接下来以 Web前端开发工程师 的角度来一个 Phonegap 的 First Blood 一.开发环境: ...