• nodejs


    --摘自廖雪峰nodejs教程

    No1:模块

    var greet = require('./hello');
    var s = 'Michael';
    greet(s);
    var s = 'Hello';
    
    function greet(name){
        console.log(s+','+name+'!')
    }
    
    module.exports = greet;

    一个模块想要对外暴露变量(函数也是变量),可以用module.exports = variable;,一个模块要引用其他模块暴露的变量,用var ref = require('module_name');就拿到了引用模块的变量。

    Node利用JavaScript的函数式编程的特性,轻而易举地实现了模块的隔离

    No2:

    JavaScript程序是由事件驱动执行的单线程模型,Node.js也不例外

    process.nextTick(function(){
        console.log('nextTick callback');
    });
    process.on('exit',function(code){
        console.log('about to exit with code: ' + code);
    });
    console.log('nextTick was set');

    结果

    nextTick was set
    nextTick callback
    about to exit with code: 0

    process也是Node.js提供的一个对象,它代表当前Node.js进程

    No3:

    fs--文件系统模块,负责读写文件

    异步读取文件中的字符串

    var fs = require('fs');
    fs.readFile('sample.txt','utf-8',function(err,data){
       if(err) {
           console.log(err);
       }else{
           console.log(data)
       }
    });

    同步读取文件

    var fs = require('fs');
    var data = fs.readFileSync('sample.txt','utf-8');
    console.log(data)

    异步写入文件

    var fs = require('fs')
    var data = 'Hello,Node.js';
    fs.writeFile('output.txt',data,function(err){
        if(err){
            console.log(err);
        }else{
            console.log('ok.');
        }
    });

    同步写入文件

    var fs = require('fs');
    var data = 'Hello,Node.js';
    fs.writeFileSync('output.txt',data);

    获取文件的详细信息

    var fs = require('fs');
    fs.stat('sample.txt',function(err,stat){
        if(err){
            console.log(err);
        }else{
            //是否是文件
            console.log('isFile:'+stat.isFile());
            //是否是目录
            console.log('isDirectory:'+stat.isDirectory());
            if(stat.isFile()){
                //文件大小
                console.log('size:'+stat.size);
                //创建时间,Data对象
                console.log('birth time:'+stat.birthtime);
                //修改时间,Data对象
                console.log('modified time:'+stat.mtime);
            }
        }
    });

    No4:

    stream--流

    读取文件

    var fs = require('fs')
    var rs = fs.createReadStream('sample.txt','utf-8')
    rs.on('data',function(chunk){
        console.log('DATA:')
        console.log(chunk);
    });
    
    rs.on('end',function(){
        console.log('END');
    });
    
    rs.on('error',function(err){
        console.log('ERROR:'+err);
    });

    写入文件

    var fs = require('fs')
    
    var ws1 = fs.createWriteStream('output1.txt','utf-8');
    ws1.write('使用Stream写入文本数据...
    ');
    ws1.write('END');
    ws1.end();
    
    var ws2 = fs.createWriteStream('output2.txt');
    ws2.write(new Buffer('使用Stream写入二进制...
    ','utf-8'));
    ws2.write(new Buffer('END.','utf-8'));
    ws2.end();

    复制文件

    var fs = require('fs');
    var rs = fs.createReadStream('sample.txt');
    var ws = fs.createWriteStream('copied.txt');
    rs.pipe(ws);

    No5:

    http

    服务器:

    var http = require('http');
    var server = http.createServer(function(request,response){
        console.log(request.method+':'+request.url);
        response.writeHead(200,{'Content-Type':'text/html'});
        response.end('<h1>Hello world!</h1>');
    });
    server.listen(8080);
    console.log('Server is running at http://127.0.0.1:8080/');

    效果

    文件服务器

    var 
        fs = require('fs'),
        url = require('url'),
        path = require('path'),
        http = require('http');
    
    var root = path.resolve(process.argv[2] || '.');
    
    console.log('Static root dir: '+root);
    
    var server = http.createServer(function(request,response){
        var pathname = url.parse(request.url).pathname;
        var filepath = path.join(root,pathname);
        fs.stat(filepath,function(err,stats){
            if(!err && stats.isFile()){
                console.log('200'+request.url);
                response.writeHead(200);
                fs.createReadStream(filepath).pipe(response);
            }else{
                console.log('404',request.url);
                response.writeHead(404);
                response.end('404 Not Found');
            }
        });
    });
    
    server.listen(8080);
    console.log('Server is running at http://127.0.0.1:8080/');

    效果

    No6:

    加密

    const crypto = require('crypto');
    const hash = crypto.createHash('md5');
    // const hash = crypto.createHash('sha1');
    hash.update('Hello,world!');
    hash.update('Hello,nodejs!');
    console.log(hash.digest('hex'));
    const crypto = require('crypto');
    const hmac = crypto.createHmac('sha256','secret-key');
    hmac.update('Hello,world!');
    hmac.update('Hello,nodejs!');
    console.log(hmac.digest('hex'));

    对称加密

    const crypto = require('crypto');
    function aesEncrypt(data,key){
        const cipher = crypto.createCipher('aes192',key);
        var crypted = cipher.update(data,'utf8','hex');
        crypted += cipher.final('hex');
        return crypted;
    }
    
    function aesDecrypt(encrypted,key){
        const decipher = crypto.createDecipher('aes192',key);
        var decrypted = decipher.update(encrypted,'hex','utf8');
        decrypted += decipher.final('utf8');
        return decrypted;
    }
    
    var data = 'Hello,this is a secret message!';
    var key = 'Password!';
    var encrypted = aesEncrypt(data,key);
    var decrypted = aesDecrypt(encrypted,key);
    
    console.log('Plain text: '+data);
    console.log('Encrypted text: '+encrypted);
    console.log('Decrypted text:'+decrypted);

    No7:

    Koa

    const Koa = require('koa');
    const app = new Koa();
    app.use(async(ctx,next)=>{
        await next();
        ctx.response.type = 'text/html';
        ctx.response.body = '<h1>Hello,koa2!</h1>';
    });

    app.listen(3000);
    console.log('app started at port 3000...');

    koa把很多async函数组成一个处理链,每个async函数都可以做一些自己的事情,然后用await next()来调用下一个async函数。我们把每个async函数称为middleware,这些middleware可以组合起来,完成很多有用的功能。

    app.use(async(ctx,next)=>{
        console.log('${ctx.request.method} ${ctx.request.url}');
        await next();
    });
    
    app.use(async(ctx,next)=>{
        const start = new Date().getTime();
        await next();
        const ms = new Date().getTime() - start;
        console.log('Time:${ms}ms');
    });
    
    app.use(async(ctx,next)=>{
        await next();
        ctx.response.type='text/html';
        ctx.response.body='<h1>Hello,koa2!</h1>';
    });

    No8:

    koa-router

    get请求

    const Koa = require('koa');
    const router = require('koa-router')();
    const app = new Koa();
    
    app.use(async(ctx,next)=>{
        console.log(`Process ${ctx.request.method} ${ctx.request.url}...`);
        await next();
    });
    
    router.get('/hello/:name',async(ctx,next)=>{
        var name = ctx.params.name;
        ctx.response.body = `<h1>Hello, ${name}!</h1>`;
    });
    
    router.get('/',async(ctx,next)=>{
        ctx.response.body = '<h1>Index</h1>';
    });
    
    app.use(router.routes());
    
    app.listen(3000);
    console.log('app started at port 3000...');

    post请求

    const Koa = require('koa');
    const router = require('koa-router')();
    const bodyParser = require('koa-bodyparser');
    const app = new Koa();
    
    app.use(async(ctx,next)=>{
        console.log(`Process ${ctx.request.method} ${ctx.request.url}...`);
        await next();
    });
    app.use(bodyParser());
    
    router.get('/',async(ctx,next)=>{
        ctx.response.body = `<h1>Index</h1>
            <form action="/signin" method="post">
                <p>Name:<input name="name" value="koa"</p>
                <p>Password:<input name="password" type="password"></p>
                <p><input type="submit" value="Submit"></p>
            </form>`;
    });
    
    router.post('/signin',async(ctx,next)=>{
        var name = ctx.request.body.name || '',
            password = ctx.request.body.password || '';
        console.log(`signin with name:${name},password:${password}`);
        if(name==='koa' && password==='12345'){
            ctx.response.body=`<h1>Welcome,${name}!</h1>`;
        }else{
            ctx.response.body=`<h1>Loginfailed!</h1>
            <p><a href="/">Try again</a></p>`;
    
        }
    });
    
    app.use(router.routes());
    
    app.listen(3000);
    console.log('app started at port 3000...');

    效果图

    No9:

    koa-router

    小型工程https://github.com/michaelliao/learn-javascript/tree/master/samples/node/web/koa/url2-koa

    No10:

    Nunjucks:模板引擎

    小型工程https://github.com/michaelliao/learn-javascript/tree/master/samples/node/web/koa/use-nunjucks

    No11:

    单元测试

    module.exports=function(...rest){
        var sum = 0;
        for(let n of rest){
            sum+=n;
        }
        return sum;
    }
    const assert = require('assert');
    const sum = require('./hello');
    
    assert.strictEqual(sum(),0);
    assert.strictEqual(sum(1),0);
    assert.strictEqual(sum(1,2),3);
    assert.strictEqual(sum(1,2,3),6);
    const assert = require('assert');
    
    const sum = require('../hello');
    
    describe('#hello.js', () => {
    
        describe('#sum()', () => {
            before(function () {
                console.log('before:');
            });
    
            after(function () {
                console.log('after.');
            });
    
            beforeEach(function () {
                console.log('  beforeEach:');
            });
    
            afterEach(function () {
                console.log('  afterEach.');
            });
    
            it('sum() should return 0', () => {
                assert.strictEqual(sum(), 0);
            });
    
            it('sum(1) should return 1', () => {
                assert.strictEqual(sum(1), 1);
            });
    
            it('sum(1, 2) should return 3', () => {
                assert.strictEqual(sum(1, 2), 3);
            });
    
            it('sum(1, 2, 3) should return 6', () => {
                assert.strictEqual(sum(1, 2, 3), 6);
            });
        });
    });

    异步测试

    const fs = require('mz/fs');
    
    // a simple async function:
    module.exports = async () => {
        let expression = await fs.readFile('./data.txt', 'utf-8');
        let fn = new Function('return ' + expression);
        let r = fn();
        console.log(`Calculate: ${expression} = ${r}`);
        return r;
    };
    const assert = require('assert');
    const hello=require('../hello');
    describe('#async hello',()=>{
        describe('#asyncCalculate()',()=>{
            it('#async with done',(done)=>{
                (async function(){
                    try {
                        let r = await hello();
                        assert.strictEqual(r,15);
                        done();
                    } catch (err) {
                        done(err);
                    }
                })();
            });
    
            it('#async function',async()=>{
                let r = await hello();
                assert.strictEqual(r,15);
            });
    
            it('#sync function',()=>{
                assert(true);
            });
        });
    });

    No12:

    为什么WebSocket连接可以实现全双工通信而HTTP连接不行呢?实际上HTTP协议是建立在TCP协议之上的,TCP协议本身就实现了全双工通信,但是HTTP协议的请求-应答机制限制了全双工通信。WebSocket连接建立以后,其实只是简单规定了一下:接下来,咱们通信就不使用HTTP协议了,直接互相发数据吧。

    const WebSocket = require('ws');
    
    const WebSocketServer = WebSocket.Server;
    
    const wss = new WebSocketServer({
        port: 3000
    });
    
    wss.on('connection',function(ws){
        console.log(`[SERVER] connection`);
        ws.on('message',function(message){
            console.log(`[SERVER] Received: ${message}`);
            setTimeout(()=>{
                ws.send(`What's your name?`,(err)=>{
                    if(err){
                        console.log(`[SERVER] error:${err}`);
                    }
                });
            });
        })
    });
    
    console.log('ws server started at port 3000...');
    
    let count = 0;
    
    let ws = new WebSocket('ws://localhost:3000/ws/chat');
    
    ws.on('open',function(){
        console.log(`[CLIENT] open()`);
        ws.send('Hello!');
    });
    
    ws.on('message',function(message){
        console.log(`[CLIENT] Received: ${message}`);
        count++;
        if(count>3){
            ws.send('Goodbye!');
            ws.close();
        }else{
            setTimeout(()=>{
                ws.send(`Hello,I'm Mr No.${count}!`);
            });
        }
    });

    效果

    ws server started at port 3000...
    app.js:23
    [SERVER] connection
    app.js:10
    [CLIENT] open()
    app.js:30
    [SERVER] Received: Hello!
    app.js:12
    [CLIENT] Received: What's your name?
    app.js:35
    [SERVER] Received: Hello,I'm Mr No.1!
    app.js:12
    [CLIENT] Received: What's your name?
    app.js:35
    [SERVER] Received: Hello,I'm Mr No.2!
    app.js:12
    [CLIENT] Received: What's your name?
    app.js:35
    [SERVER] Received: Hello,I'm Mr No.3!
    app.js:12
    [CLIENT] Received: What's your name?
    app.js:35
    [SERVER] Received: Goodbye!
    app.js:12
    [SERVER] error:Error: not opened

    欢迎关注我的微信公众号:安卓圈

  • 相关阅读:
    创始人透露Twitter新盈利计划:第三方将受益
    试试ScribeFire转发我的其它博客
    2009年12月30日:新网因清除URL转发域名导致DNS解析故障
    VS2008 如果更改源代码管理插件,将关闭活动解决方案或项目
    Linq使用Group By经验总结
    使用C#的BitmapData
    Java与C#开发上的一些差异与转换方法
    成都七中成绩文件导入SQL脚本
    用SQL SERVER对EXCEL数据进行处理
    NULLIF和ISNULL
  • 原文地址:https://www.cnblogs.com/anni-qianqian/p/10483719.html
Copyright © 2020-2023  润新知