学习Node.js的简单记录

本篇博客原本是作为长期记录使用,因为域名进行备案导致一个月并没有进行更新。当再次编辑的时候,中间已经跨度一个月,两次实际上已经不是一个水准,导致全文多次修改,乱乱糟糟。

前言

在之前了解了前端UI框架,不由想写一些web端的项目。便想要学习一门后端语言,为了简单快速的入门,选择了node.js.

特性

NodeJS有两个重要的概念,

非阻塞I/Q

当系统进行I/Q操作的时候会进行等待操作完成才会按照顺序执行下一条语句,这样就叫做阻塞I/Q,而非阻塞显然反之。

像Node.js 属于全局异步,这一个概念实际上非常重要,因为没有理解,后面导致在编写项目的时候浪费了很长时间!

事件驱动

简单的说,node.js所有的操作几乎都是依靠回调函数进行控制。




Node.JS配置非常简单,这里就不再记录。

建立websever并响应URL

本着迫切获得反馈的想法,第一步就要先把之前编写的登录页面渲染出来!

实际上像apache这种服务器软件,都会自动根据url进行响应对于的文件..我不清楚为啥NodeJS需要自己编写...不过也算是入门实例吧!

项目目录。

image.png

在Node.js中建立webserver很简单,先使用require()导入模块,再通过 createServer()创建就行。

 var http = require('http'); 

createServer()的第一个参数是一个回调函数,分别有两个参数,

http.createServer(function(request,respone){     });

  • request

请求对象,可以可以通过这个参数监听每次请求包中的信息。

  • respone

响应对象,通过这个参数进行响应请求。




总的来说,当有一个url进行访问时候,我们需要通过request参数进行得知它需求的是那个文件,然后再通过respone参数进行响应。




之后思路就很简单了。我们只需要把获取到本地的文件,将他返回出去就大功告成。

一般的,本地操作需要使用FS模块 require('fs') 导入即可。

第一个参数是目标文件的路径,第二个是回调函数。回调函数中第一个err参数是指是否出错,第二个则是我们获取到的文件内容。

我们获取成功后通过 respone.end()进行返回我们文件的内容即可。

fs.readFile('./index.html', function(err, data) {
             if (err) {
                 console.error(err);
                 return;
             }
             respone.end(data);
         });

到这里基本上就ok了,我们只需要再设置一下监听的端口。

http.listen(8080);

不过我们一般直接在创建server后面加上.listen()函数就可以了。

下面是完整的代码:

http.createServer(function(request,respone){
    var url = request.url;
    if(url=='/'){
        respone.writeHead(200,{'Content-Type':'text/html'});
         var ns = fs.readFile('./index.html', function(err, data) {
             if (err) {
                 console.error(err);
                 return;
             }
             respone.end(data);
         });
    }else if(url != '/'){
        var cpurl = '.'+url;
        var type = url.substr(url.lastIndexOf(".")+1,url.length)
        respone.writeHead(200,{'Content-type':"text/"+type});
        var ns = fs.readFile(cpurl, function(err, data) {
            if (err) {
                console.error(err);
                return;
            }
            respone.end(data);
        });
    }
}).listen(8080);

自此,当我打开 http://127.0.0.1:8080/login.html的时候,便会渲染出login.html页面。

image.png

使用Koa2框架

Koa2是Node.js的一个web开发框架。为什么使用?因为我懒。

安装Koa2

VsCode在终端中直接输入指令

npm init // 初始化package.json
npm i koa // 安装koa2

使用Koa2后的改变

const Koa = require('koa');
const fs  = require('fs');
app.use(async ctx => {
    ctx.type='html';    
    ctx.body = fs.createReadStream('./index.html');
});
app.listen(3000);

上图代码不难看出,大概意思就是说通过fs函数载入index.html内容赋给ctx参数中的body。打开127.0.0.1:3000后便会发现,直接载入了index.html.

简单的来说,Koa2框架直接把原先http.createServer()和回调函数两个参数都集成在async函数的ctx函数中,并且回调函数的语法方式更改成了箭头式 ( “=>”)。

载入静态文件

在websever的时候,难免需要响应诸如CSS、图片、等一系列的静态文件,我们并不可能每一次响应都要通过代码进行声明。而像我在之前编写的webserver的逻辑是:寻找url之后的文件

很显然,这是一个错误的方法,当时也没有进行思考,草草的以完成“任务”为标准,踩下了这个坑。正确的操作方式应该是直接通过路由。像以前学习php的时候,这些操作实际上apache已经帮我们写好了。

路由会在下面记录,回到正题。 因此,这些静态文件我们可以通过koa-static进行操作为对外开放。说白了就是让别人可以直接通过url进行自动响应。

安装 koa-static

终端置入以下指令

npm install koa-static --save

直接通过以下代码即可设置静态目录。static函数下第二个参数(./www)就是你要设置的静态目录。

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

接下来就可以愉快的使用文件啦~

路由

前面说到,我们之前在编写webserver的响应方式是错误的,这里记录路由。这里使用的路由模块是“koa-router ”.

通过路由绑定一个地址,然后对其做出响应。

router.get('/login',async ctx=>{
//做出响应的操作
router.render('login'); //模板引擎,跳转到login.html,下面会介绍。
});

如果你足够细心,可以看到,在router后面使用一个了‘.get’ ,通过标题你应该可以联想到GET操作吧?实际上我们每一个http请求,你都可以理解为他是一个get请求,只是带不带数据的区别而已。

代码编辑完之后写下以下代码即可启动router.

app.use(router.routes());

我们现在已经得知如何简单的使用路由了,那么还是使用之前的fs进行读取文件吗? 那个太麻烦了,我们现在再换一个新家伙——模板引擎

模板引擎

在编写项目中,模板引擎在其中帮助我实现了以下两个方面:

其一是,配合路由进行响应内容,其二是通过模板参数更改HTML内容。

初始化

render(app, {
    root: path.join(__dirname, 'views'),  
    extname: '.html',  
    debug: process.env.NODE_ENV !== 'production' 
  });

“views” 是指你的项目模块地址。 一般情况下只需要更改第一个参数即可。

使用

在前面的路由中我们已经看到了,router.render('login'); 的后面我注释有,“响应到login.html”。 然后根据初始化的代码进行理解,大概就是:

响应views模板目录下的login.html。

实际上router.render不仅仅只有一个参数,第二个参数便是我上文所说的,修改HTML内容。说白了就是在加载的同时,替换HTML的内容。

router.render('login',{
url: 'www.baidu.com' 
});

你应该猜到了,上述代码会将下面img标签的src更改为 ‘www.baidu.com’ 。的确是这样 {{url}}这个文本对应的正是上述代码中的url参数。

值得注意的是,在html中填写的参数如果名字相同,那么会多次赋值。

image.png

Mysql

mysql没什么好说的,无非就是链接到数据库,然后运行sql命令。不过因为node.js异步的特性,这里需要使用promise,这点需要记录一下。

const mysql  = require('mysql');  
const MYSQL_DB_CONFIG={
    localhost:'localhost',
    user:'root',
    password:'root',
    port:'3306',
    database:'qndxx'
} 
const con=mysql.createConnection(MYSQL_DB_CONFIG);
con.connect();

function exec(sql){  
  const promise=new Promise((resolve,reject)=>{
    con.query(sql,(err,results)=>{
      if(err){
        reject(err);
        return;
      }
      resolve(results);
    })
  })
  return promise;
}