美文网首页
Node.js学习

Node.js学习

作者: 5df463a52098 | 来源:发表于2018-09-10 16:19 被阅读19次

    Node.js学习计划(一)——模块化编程

    一、创建模块

    手动创建一个项目结构:


    image.png

    wise-modules存放模块,app.js是入口文件。
    wise-modules下创建模块hello:

    'use strict';
    function hello(name) {
        console.log('hello', name);
    }
    module.exports = hello;
    

    app.js中引入模块

    'use strict';
    let hello = require('./wise_module/hello');
    hello('test');
    

    二、了解require

    image.png
    可以看到 require 后面接的是相对路径,如果改成下图:
    image.png
    就会发生异常,提示找不到对应模块。
    这是因为在没有具体路径的时候,require 会首先检查 node.js 核心模块(如 "fs"),然后检查 node_modules,最后检查环境变量 NODE_PATH 指定的目录。
    将hello.js放进node-modules目录下:
    image.png
    image.png
    这样就能正常编译了。
    上面的 hello 模块是一个 js 文件,如果 hello 是一个文件夹,就需要在目录下创建一个 index.js 作为模块的入口。实际项目中,node_modules 是由 package.json 生成,里面用来存放第三方依赖库。自己开发的模块还是需要放到其他文件目录下,然后通过 require( /相对路径/ ) 引入。

    三、模块的两种导出方式

    1、exports导出


    image.png
    image.png

    用 exports 这种方式导出的时候,将 hello 函数作为导出对象的一个键值给暴露出来
    2、module.exports导出


    image.png
    image.png
    看起来 exports 变量和 module.exports 变量似乎是同一个变量,但实际上还是有些区别,比如 exports 不能直接赋值。
    exports 作为 module.exports 的衍生产物,虽然可以应对大多数情况,但仍有不足之处,所以模块导出的时候,建议使用 module.exports = * 这种方式来输出。

    Node.js学习计划(二)——使用http模块搭建web服务器

    创建项目结构:


    image.png

    服务端server.js

    let http = require('http');
    let fs = require('fs');
    let url = require('url');
    let path = require('path');
    let qs = require('querystring');
    let c = require('child_process');
    
    let server = http.createServer(function (req, res) {
    
        // 获取根目录
        let root = path.resolve('.');
        // 获取请求路径
        let filePath = url.parse(req.url).pathname;
        if (filePath === '/') filePath = '/index.html';
        // 生成文件路径
        let absPath = path.join(root, '/public', filePath);
    
        switch (req.method) {
            case 'GET':
                // 从硬盘读取文件
                fs.readFile(absPath, function (err, data) {
                    if (err) {
                        // 重写响应头,返回 404
                        res.writeHead(404, { 'Content-Type': 'text/plain' });
                        // 响应文件内容
                        res.write("not found");
                    } else {
                        // 重写响应头,返回 200
                        res.writeHead(200, { 'Content-Type': 'text/html' });
                        // 响应文件内容
                        res.write(data);
                    }
                    //  结束响应,发送数据
                    res.end();
                });
                break;
    
            case 'POST':
                let postData = '';
                // 监听 data 事件
                req.on("data", function (chunk) {
                    // 拼接 post 过来的数据
                    postData += chunk;
                });
                // 监听 end 事件
                req.on("end", function () {
                    // 使用 querystring 模块将字符串数据转为对象
                    let queryData = qs.parse(postData);
                    // 将数据以 json 字符串的形式保存到文件中
                    fs.writeFile(path.join(__dirname, 'wise.txt'), JSON.stringify(queryData), function (err) {
                        if (err) throw err;
                        console.log("Export Account Success!");
                    });
                    // 重写响应头
                    res.writeHead(200, { "Content-Type": "text/plain" });
                    res.end("success");
                });
                break;
        }
    });
    
    server.listen(4567, function () {
        console.log('Server listening on port 4567');
        // 服务启动成功后打开对应链接
        c.exec('start http://localhost:4567/');
    });
    

    客户端请求form.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <form method="post">
        <div>
            <label for="name">用户名</label>
            <input type="text" name="name">
        </div>
        <div>
            <label for="tell">联系方式</label>
            <input type="text" name="tell">
        </div>
        <div>
            <label for="gender">性别</label>
            <input type="radio" name="gender" checked>男
            <input type="radio" name="gender">女
        </div>
        <div>
            <label for="address">籍贯</label>
            <input type="text" name="address">
        </div>
        <button type="submit">提交</button>
    </form>
    </body>
    </html>
    

    开启服务:node ./lib/server.js
    浏览器http://localhost:4567/打开的是index.html,页面是空。
    打开http://localhost:4567/form.html

    image.png
    返回结果:
    image.png

    Node.js学习计划(三)——express起航

    一、创建项目

    1、安装:

    npm install -g express-generator
    npm install -g express
    express --version   // 验证是否安装成功
    

    // 如果了解过 vue,express-generator 和 express 的关系就像 vue-cli 和 vue 的关系
    2、创建项目

    express node-express
    
    image.png

    3、进入目录,安装依赖

    cd node-express/
    npm install
    

    4、启动命令

    npm start
    

    开发过程中建议在 debug 环境中运行,所以通常使用这个命令启动项目:

    set DEBUG=node-express & npm start
    

    二、认识路由

    在生成的项目文件中,有一个 routes 文件夹,存放着 express 框架预置的基本路由


    image.png

    上图中的 users.js 是一个最简单的路由

    var express = require('express');
    var router = express.Router();
    /* GET users listing. */
    router.get('/', function(req, res, next) {
      res.send('respond with a resource');
    });
    module.exports = router;
    

    然后在 app.js 中引入模块

    var usersRouter = require('./routes/users');
    

    并配置路由结点

    app.use('/users', usersRouter);
    

    然后在浏览器中打开 http://localhost:3000/users 就能查看到响应内容

    image.png
    如果希望路由对外输出一个 html 页面,只需要使用 res.sendfile(url)
    假如已经在 views 文件夹下准备了一个模板 test.html,然后在 users.js 中追加一个句柄
    router.get('/test', function(req, res) {
      res.sendfile("./views/test.html")
    });
    

    然后打开 http://localhost:3000/users/test 就能查看到 test.html

    image.png

    三、托管静态文件

    如果刚才的 test.html 文件中,关联了 views 文件夹下的外部 css 或者 js 文件,就会发现这些文件都没有被加载,只要将 css 文件放到 public 文件夹下,并将文件路径改为绝对路径


    image.png
    <link rel="stylesheet" href="/stylesheets/test.css">
    

    这样外部文件就能正常加载了,甚至可以通过http://localhost:3000/stylesheets/test.css 查看到对应的 css 文件

    image.png
    这是因为在 app.js 中,已经通过 express.static 中间件将 public 文件夹设置为静态资源的根目录
    app.use(express.static(path.join(__dirname, 'public')));
    

    静态资源目录可以有多个,只需要多次调用 express.static 就行

    app.use(express.static('public'));
    app.use(express.static('wise'));
    app.use(express.static('wrong'));
    

    访问静态资源文件时,express.static 中间件会根据目录添加的顺序查找文件
    express 允许给这些文件夹指定一个虚拟挂载点

    app.use('/static', express.static('public'));
    

    这样就能通过带有 “/static” 前缀的地址来访问 public 目录下面的文件
    比如之前的 test.css 文件的地址就变成了 http://localhost:3000/static/stylesheets/test.css
    如果有多个静态资源目录,还可以把它们都指定在同一个挂载点下

    app.use('/static' ,express.static(path.join(__dirname, 'public')));
    app.use('/static' ,express.static(path.join(__dirname, 'wise')));
    app.use('/static' ,express.static(path.join(__dirname, 'wrong')));
    

    这种方式必须要保证每个文件的路径不会冲突,如果多个文件都是同一个路径,就只有第一个文件能被正常访问。
    四、中间件
    上面有提到 express.static 是一个中间件,在软件领域中,中间件在应用与应用之间起到连接的作用。在 express 中,中间件就是处理 http 请求的各种函数,这些函数通过 next() 方法连接,形成了一个流水线。
    中间件一般用 app.use() 注册,针对不同的请求,还可以使用 all 或者 HTTP 动词作为方法名,如 get、post,中间件可以接收三个参数,依次为 request(HTTP请求)、response(HTTP响应),next 回调函数(下一个中间件)。每个中间件都可以对 request 进行加工,并使用 next() 将 request 对象传给下一个中间件。

    app.use(function(req,res,next){
        // doing something
        next()
    })
    

    如果向 next() 传入参数(字符串 ‘route’ 除外),则代表抛出一个错误,参数为错误文本

    app.use(function(req,res,next){
        // doing something
        next('error')
    })
    

    而后的中间件将不再执行,直到发现一个错误处理函数为止。
    在注册中间件的时候,还可以传入一个 url,让中间件的调用具有针对性

    app.use('/home', function(req,res,next){
        // doing something
        next()
    })
    

    比如这个例子,只会对路径前缀为 “/home” 的请求调用中间件
    express 其实就是由路由和中间件构成的,从本质上来说,一个 express 应用就是在调用各种中间件。

    Node.js学习计划(四)——express+sql server

    一、创建项目

    express node-movie
    

    因为使用 SQL Server 作为数据库,所以需要引入 mssql 模块
    安装:

    npm install --save mssql jquery bootstrap
    

    将 views 目录设置为视图目录,用来存放静态页面,并且只识别 .jade 类型的文件,修改app .js

    app.set('views', path.join(__dirname, 'views'));
    app.set('view engine', 'jade');
    // 如果直接使用 .html 文件,就需要把第二行代码改为
    // app.set('view engine', 'html');
    

    jade语法,推荐学习博文(https://segmentfault.com/a/1190000000357534)
    如果需要引入 css 或者 js,一般是css 和 js 文件拷贝到 public 目录下,然后在页面中引入,项目中需要引入 bootstrap,如果以这种方式引入,还得去 node_modules 目录下找到对应的文件。

    app.use('/lib', express.static(path.join(__dirname, 'node_modules')));
    

    引入文件:

        link(rel='stylesheet', href='/static/stylesheets/style.css')
        link(rel='stylesheet', href='/lib/bootstrap/dist/css/bootstrap.min.css')
        script(src="/lib/jquery/dist/jquery.min.js")
    

    二、创建路由

    在routes目录下床建页面对应的路由
    如routes/index.js

    var express = require('express');
    var router = express.Router();
    /* GET home page. */
    router.get('/', function(req, res, next) {
       res.render('index'); // 对应views目录下的index.jade
    });
    module.exports = router;
    

    然后在app.js里引入:

    var index = require('./routes/index');
    

    在 app.js 中配置路由结点

    app.use('/', index);
    //重定向
    app.get('/index', function (req, res) {
        res.redirect('/')
    })
    

    然后在浏览器中打开项目,就能正确的渲染页面了

    二、创建数据库

    安装推荐文章,(https://www.cnblogs.com/xuyatao/p/6932885.html

    三、连接数据库

    创建配置项

    var config = {
        user: 'root',
        password: '123456789',
        server: 'localhost',
        database: 'mydatabase'
    }
    

    连接数据库

    const sql = require('mssql')
    router.get('/', function(req, res, next) {
       sql.connect(config).then(() => {
            // 插入SQL语句
            return sql.query`select * from movies`
        }).then(result => {
            res.render('index', {
                title: 'WiseWrong',
                movies: result.recordset //查询结果
            });
            sql.close(); // 断开数据库的连接,很关键
        }).catch(err => {
            res.render('error');
            console.log('出错了 ', err);
        })
        sql.on('error', err => {
            res.render('error');
            console.log('出错了 ', err);
        })
    });
    

    不过在连接数据库过程中出错了,报错内容如下:


    image.png

    Node.js学习计划(五)——Koa基础项目搭建

    一、创建项目

    1、创建一个文件夹node-koa,生成package.json文件,安装Koa

    npm init -y //  生成package.json
    npm install koa -S //  安装Koa
    

    2、创建一个app.js

    const Koa = require('koa');
    const app = new Koa();
    
    app.use(async ctx => {
        ctx.body = 'koa 开始了';
    });
    app.listen(3000);
    

    3、package.json添加命令


    image.png

    4、启动命令:

    npm start
    

    5、打开浏览器http://localhost:3000/

    image.png

    二、配置路由

    上面 app.js 中有一个 ctx,这是一个 Koa 提供的 Context 对象,封装了 request 和 response,每一次 HTTP Request 都会创建一个 Context 对象。
    我们可以通过 Context.request.path 来获取用户请求的路径,然后通过 Context.response.body 给用户发送内容,Koa 默认的返回类型是 text/plain,如果要返回一个 html 文件(或者一个模块文件),就需要修改 Context.response.type。另外,Context.response 可以简写,比如 Context.response.type 简写为 Context.type,Context.response.body 简写为 Context.type。
    在项目目录下创建存放html的文件夹views,并在该目录下创建一个 index.html,然后修改 app.js

    const Koa = require('koa');
    const fs = require('fs');
    const app = new Koa();
    app.use(async (ctx, next) => {
        // ctx.body = 'koa 开始了';
        if (ctx.request.path === '/index') {
            ctx.type = 'text/html';
            ctx.body = fs.createReadStream('./views/index.html');
           // 使用fs读取html文件
        } else {
            await next();
        }
    });
    app.listen(3000);
    

    重启命令,打开浏览器http://localhost:3000/index就能看到index .html页面,而访问别的地址则是 not found。

    image.png
    image.png

    引入路由中间件koa-router

    npm install koa-router -S
    

    创建一个 routes 目录,用来存放路由文件,并在目录下创建 index.js


    image.png

    routes/index.js:

    const fs = require('fs');
    const router = require('koa-router')()
    router.get('/index', async (ctx, next) => {
        ctx.type = 'text/html';
        ctx.body = fs.createReadStream('./views/index.html');
    });
    module.exports = router
    

    修改app.js:

    const Koa = require('koa');
    const fs = require('fs');
    const router = require('koa-router')();
    // 相当于
    // const koaRouter = require('koa-router');
    // const router = koaRouter();
    const app = new Koa();
    
    /*app.use(async (ctx, next) => {
        // ctx.body = 'koa 开始了';
        if (ctx.request.path === '/index') {
            ctx.type = 'text/html';
            ctx.body = fs.createReadStream('./views/index.html');
        } else {
            await next();
        }
    });*/
    const index = require('./routes/index')
    app.use(index.routes(), index.allowedMethods())
    //allowedMethods 用于校验请求的方法,如果用 post 请求访问 get 接口,就会直接返回失败
    app.listen(3000);
    

    另外,还可以在 url 中添加变量,然后通过 Context.params.name 访问

    router.get('/about/:name', async (ctx, next) => {
      ctx.body = `I am ${ctx.params.name}!`;
    });
    

    三、静态资源

    在上面的 index.html 中,如果需要引入 css 等静态资源,就需要用到 koa-static

    npm install koa-static -S
    

    创建一个目录 public 用来存放静态资源


    image.png

    修改app.js:

    const static = require('koa-static');
    // 将 public 目录设置为静态资源目录
    const main = static(__dirname + '/public');
    app.use(main);
    // 优化app.use(require('koa-static')(__dirname + '/public'));
    

    然后就能在 index.html 中引入对应的文件了,/public默认就是静态资源的根目录

    <link rel="stylesheet" href="/css/reset.css">
    
    image.png

    四、模板引擎

    上面的路由是使用 fs 模块直接读取 html 文件,开发的时候更推荐使用koa-views中间件来渲染页面。
    在 app.js 中将 views 目录设定为模版目录

    const views = require('koa-views')
    app.use(views(__dirname + '/views'));
    

    然后在路由文件中,就能使用 render 方法了。

    // routes/index.js
    const router = require('koa-router')()
    router.get('/index', async (ctx, next) => {
      await ctx.render('index');
    });
    module.exports = router
    

    以上是直接渲染 html 文件的方法,如果要引入模板引擎,可以添加 extension 字段来设定模版类型。

    app.use(views(__dirname + '/views', {
      extension: 'pug'    // 以 pug 模版为例
    }))
    

    如果将 Express 看作 webstorm,那么 Koa 就是 sublime。当 Express 流行的时候,其冗杂的依赖项被很多开发者所诟病。所以 Express 团队将 Express 拆卸得只剩下最基本的骨架,让开发者自行组装,这就是 Koa。Koa也有自己的脚手架koa-generato,使用脚手架进行快速开发。
    推荐[博文]: (https://www.cnblogs.com/wisewrong/category/1042889.html)

    相关文章

      网友评论

          本文标题:Node.js学习

          本文链接:https://www.haomeiwen.com/subject/ecwsgftx.html