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. java 文件过滤

    public class TestFileio { public static void main(String[] args) { File file = new File("D:/upl ...

  2. 开源工具 | 手游自动化框架GAutomator,新增iOS系统和UE4引擎支

    WeTest 导读 GAutomator是腾讯WeTest推出的手游自动化测试框架,已用于腾讯多个手游项目组的自动化测试. 1.GAutomator诞生背后 研究过手游自动化测试的同学都知道,虽然市场 ...

  3. JS继承方法

    1.原型链: 每个构造函数都有一个原型对象,且有一个指针指向该原型对象(prototype),原型对象都包含一个指向构造函数的指针(constructor),而实例都包含一个指向原型对象的内部指针(p ...

  4. Qt-Qt5最新增加程序图标方式

    亲爱的小伙伴吗,还记得原始的Qt4是怎么给运行程序添加图标的么,是不是先准备一个ICON文件,问了在家里建立一个rc文件,在文件里面加上 IDI_ICON1               ICON    ...

  5. (转)python+opencv实现动态物体追踪

    原文链接:https://blog.csdn.net/cike14/article/details/50649811 import cv2 import numpy as np camera=cv2. ...

  6. 华为笔试——C++的int型数字位排序

    题目:int型数字位排序 题目介绍:输入int 型整数,按照从右至左的顺序,返回不含重复数字的新整数. 例: 输入: 99824270 输出: 072489 分析:乍一看很简单,但是很容易忽略int ...

  7. android点击事件的四种方式

    android点击事件的四种方式 第一种方式:创建内部类实现点击事件 代码如下: package com.example.dail; import android.text.TextUtils; im ...

  8. [leetcode-884-Uncommon Words from Two Sentences]

    We are given two sentences A and B.  (A sentence is a string of space separated words.  Each word co ...

  9. USACO 1.3.2 Barn Repair 修理牛棚(贪心)

    Description 在一个夜黑风高,下着暴风雨的夜晚,农民约翰的牛棚的屋顶.门被吹飞了. 好在许多牛正在度假,所以牛棚没有住满. 剩下的牛一个紧挨着另一个被排成一行来过夜. 有些牛棚里有牛,有些没 ...

  10. MathExam第二次作业(升级版)

    MathExamLv2——林华伟 211506319 陈珍 211406263   一.预估与实际 PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实 ...