Node.jsWeb前端之路让前端飞

node.js概述

2017-06-25  本文已影响85人  琪先生_zZ

简介


Node.js是事件驱动的


路由

                               url.parse(string).query
                                           |
           url.parse(string).pathname      |
                       |                   |
                       |                   |
                     ------ -------------------
http://localhost:8888/start?foo=bar&hello=world
                                ---       -----
                                 |          |
                                 |          |
              querystring(string)["foo"]    |
                                            |
                         querystring(string)["hello"] 

工具


框架 Express

// 这句的意思就是引入 `express` 模块,并将它赋予 `express` 这个变量等待使用。
var express = require('express');
// 调用 express 实例,它是一个函数,不带参数调用时,会返回一个 express 实例,将这个变量赋予 app 变量。
var app = express();

// app 本身有很多方法,其中包括最常用的 get、post、put/patch、delete,在这里我们调用其中的 get 方法,为我们的 `/` 路径指定一个 handler 函数。
// 这个 handler 函数会接收 req 和 res 两个对象,他们分别是请求的 request 和 response。
// request 中包含了浏览器传来的各种信息,比如 query 啊,body 啊,headers 啊之类的,都可以通过 req 对象访问到。
// res 对象,我们一般不从里面取信息,而是通过它来定制我们向浏览器输出的信息,比如 header 信息,比如想要向浏览器输出的内容。这里我们调用了它的 #send 方法,向浏览器输出一个字符串。
app.get('/', function (req, res) {
  res.send('Hello World');
});

// 定义好我们 app 的行为之后,让它监听本地的 3000 端口。这里的第二个函数是个回调函数,会在 listen 动作成功后执行,我们这里执行了一个命令行输出操作,告诉我们监听动作已完成。
app.listen(3000, function () {
  console.log('app is listening at port 3000');
});

补充知识


package.json

// 引入依赖
var express = require('express');
var utility = require('utility');

// 建立 express 实例
var app = express();

app.get('/', function (req, res) {
  // 从 req.query 中取出我们的 q 参数。
  // 如果是 post 传来的 body 数据,则是在 req.body 里面,不过 express 默认不处理 body 中的信息,需要引入 https://github.com/expressjs/body-parser 这个中间件才会处理,这个后面会讲到。
  // 如果分不清什么是 query,什么是 body 的话,那就需要补一下 http 的知识了
  var q = req.query.q;

  // 调用 utility.md5 方法,得到 md5 之后的值
  // 之所以使用 utility 这个库来生成 md5 值,其实只是习惯问题。每个人都有自己习惯的技术堆栈,
  // 我刚入职阿里的时候跟着苏千和朴灵混,所以也混到了不少他们的技术堆栈,仅此而已。
  // utility 的 github 地址:https://github.com/node-modules/utility
  // 里面定义了很多常用且比较杂的辅助方法,可以去看看
  var md5Value = utility.md5(q);

  res.send(md5Value);
});

app.listen(3000, function (req, res) {
  console.log('app is running at port 3000');
});

$ node app.js

访问 http://localhost:3000/?q=alsotang,完成。


使用 superagent 与 cheerio 完成简单爬虫

知识点

知识内容

新建项目

要求

app.get('/', function (req, res, next) {
  // 用 superagent 去抓取 https://cnodejs.org/ 的内容
  superagent.get('https://cnodejs.org/')
    .end(function (err, sres) {
      // 常规的错误处理
      if (err) {
        return next(err);
      }
      // sres.text 里面存储着网页的 html 内容,将它传给 cheerio.load 之后
      // 就可以得到一个实现了 jquery 接口的变量,我们习惯性地将它命名为 `$`
      // 剩下就都是 jquery 的内容了
      var $ = cheerio.load(sres.text);
      var items = [];
      $('#topic_list .topic_title').each(function (idx, element) {
        var $element = $(element);
        items.push({
          title: $element.attr('title'),
          href: $element.attr('href')
        });
      });

      res.send(items);
    });
});

异步并发


eventproxy

var eventproxy = require('eventproxy');
var ep = new eventproxy();
ep.all('data1_event', 'data2_event', 'data3_event', function (data1, data2, data3) {
  var html = fuck(data1, data2, data3);
  render(html);
});

$.get('http://data1_source', function (data) {
  ep.emit('data1_event', data);
  });

$.get('http://data2_source', function (data) {
  ep.emit('data2_event', data);
  });

$.get('http://data3_source', function (data) {
  ep.emit('data3_event', data);
  });

ep.all('data1_event', 'data2_event', 'data3_event', function (data1, data2, data3) {});


作用域与闭包:this,var,(function () {})

闭包
    for(var i=0; i<10; i++){
        (function (j){
          return setTimeout(function(){                
                console.log(j);
            },0)
        })(i) 
    }
this

mongodb

mongodb 的官网是这样介绍自己的:
MongoDB (from "humongous") is an open-source document database, and the leading NoSQL database. Written in C++


mongoose

// 首先引入 mongoose 这个模块
var mongoose = require('mongoose');
// 然后连接对应的数据库:mongodb://localhost/test
// 其中,前面那个 mongodb 是 protocol scheme 的名称;localhost 是 mongod 所在的地址;
// 端口号省略则默认连接 27017;test 是数据库的名称
// mongodb 中不需要建立数据库,当你需要连接的数据库不存在时,会自动创建一个出来。
// 关于 mongodb 的安全性,mongodb 我印象中安全机制很残废,用户名密码那套都做得不好,更
// 别提细致的用户权限控制了。不过不用担心,mongodb 的默认配置只接受来自本机的请求,内网都连不上。
// 当需要在内网中为其他机器提供 mongodb 服务时,或许可以去看看 iptables 相关的东西。
mongoose.connect('mongodb://localhost/test');

// 上面说了,我推荐在同一个 collection 中使用固定的数据形式。
// 在这里,我们创建了一个名为 Cat 的 model,它在数据库中的名字根据传给 mongoose.model 的第一个参数决定,mongoose 会将名词变为复数,在这里,collection 的名字会是 `cats`。
// 这个 model 的定义是,有一个 String 类型的 name,String 数组类型的 friends,Number 类型的 age。
// mongodb 中大多数的数据类型都可以用 js 的原生类型来表示。
//至于说 String 的长度是多少,Number 的精度是多少。String 的最大限度是 16MB,Number 的整型是 64-bit,浮点数的话,js 中 `0.1 + 0.2` 的结果都是乱来的。
// 这里可以看到各种示例:http://mongoosejs.com/docs/schematypes.html
var Cat = mongoose.model('Cat', {
  name: String,
  friends: [String],
  age: Number,
});

// new 一个新对象,名叫 kitty
// 接着为 kitty 的属性们赋值
var kitty = new Cat({ name: 'Zildjian', friends: ['tom', 'jerry']});
kitty.age = 3;

// 调用 .save 方法后,mongoose 会去你的 mongodb 中的 test 数据库里,存入一条记录。
kitty.save(function (err) {
  if (err) // ...
  console.log('meow');
});
我们也可以将对应的数据模型导出接口对象,
用来给controller使用,控制器根据对应的逻辑调用对应的"增删改查"

import mongoose from 'mongoose'

mongoose.connect('mongodb://localhost/edu')

const advertSchema = mongoose.Schema({
  title: { type: String, required: true },
  image: { type: String, required: true },
  link: { type: String, required: true },
  start_time: { type: Date, required: true },
  end_time: { type: Date, required: true },
  create_time: { type: Date, default: Date.now },
  last_modified: { type: Date, default: Date.now }
})

export default mongoose.model('Advert', advertSchema)

数据库基本操作:

$ mongo
MongoDB shell version: 2.6.4
connecting to: test
> show dbs
> use test
> show collections
> db.cats.find()

connect 中间件


get方法和post方法获取查询字符数据

//获取当前请求路径的一些信息
//第二个参数传入true,将查询字符串解码成对象
var urlObj = url.parse(decodeURI(req.url), true);
res.query = urlObj.query;   //请求信息
// chunk 是一个二进制数据
var body = ''
req.on('data', function (chunk) {
    body += chunk
})
// 当 Node 接收完毕表单 POST 提交的数据的时候,会触发 req 请求对象的 end 事件,执行对应的回调处理函数
req.on('end', function () {
    // 使用核心模块 querystring 的 parse 方法将一个查询字符串转为一个对象
    body = querystring.parse(body)

这样body就是我们需要获取的请求数据

mondule和exports.mondule


express(第三方框架)

一个基于 Node 开发的一个快速 Web 开发框架
主要用来构建 Server
Express 4.x API 中文手册

处理静态资源

通过 Express 内置的express.static可以方便地托管静态文件,例如图片、CSS、JavaScript 文件等。

配置规则如下:

app.use('访问前缀', express.static('资源目录路径'))
在 Express 中配置使用 body-parser 插件解析处理表单 POST 请求体

第一步:安装 body-parser

npm install --save body-parser

第二步,在代码中进行配置:

app.use(bodyParser.urlencoded({ extended: false }))
app.use(bodyParser.json())
ejs 第三方模块

Express 这个框架很精简,默认是不支持模板引擎的,需要配合一些第三方的模板引擎来结合使用,
在代码中配置:

app.set('views', 模板文件存储路径) // 注意,这里可以不配置,因为 Express 默认会去项目中的 `views` 目录进行查找
app.set('view enginge', 'ejs') // 这里表示让 Express 中的 res.render 方法使用 ejs 模板引擎,这里的 ejs 就是你安装的那个模板引擎的包名

只要经过了上面这种配置,然后 res 对象上就会自动多出一个方法:res.render ,使用方式和咱们之前自己封装的一样:res.render('视图名称', {要解析替换的对象数据})

注意:使用了 ejs 模板引擎,默认视图文件后缀名必须是 .ejs,否则 render 方法找不到。
如果想要修改,可以像下面这样:

// app.set('view enginge', 'ejs')
// 将上面这句配置改为下面的形式,就修改了默认的 .ejs 后缀名
app.engine('.html', require('ejs').__express)
app.set('view engine', 'html')
Nunjucks 模板引擎
//加载定义好的模版文件
//在模版文件中留有对应的坑
{% extends "base.html" %}
//写入自己想要的代码
{% block header %}
//代码
{% endblock %}

{% block content %}
//代码
{% endblock %}

上一篇 下一篇

猜你喜欢

热点阅读