本篇博客原本是作为长期记录使用,因为域名进行备案导致一个月并没有进行更新。当再次编辑的时候,中间已经跨度一个月,两次实际上已经不是一个水准,导致全文多次修改,乱乱糟糟。
前言
在之前了解了前端UI框架,不由想写一些web端的项目。便想要学习一门后端语言,为了简单快速的入门,选择了node.js.
特性
NodeJS有两个重要的概念,
非阻塞I/Q
当系统进行I/Q操作的时候会进行等待操作完成才会按照顺序执行下一条语句,这样就叫做阻塞I/Q,而非阻塞显然反之。
像Node.js 属于全局异步,这一个概念实际上非常重要,因为没有理解,后面导致在编写项目的时候浪费了很长时间!
事件驱动
简单的说,node.js所有的操作几乎都是依靠回调函数进行控制。
Node.JS配置非常简单,这里就不再记录。
建立websever并响应URL
本着迫切获得反馈的想法,第一步就要先把之前编写的登录页面渲染出来!
实际上像apache这种服务器软件,都会自动根据url进行响应对于的文件..我不清楚为啥NodeJS需要自己编写...不过也算是入门实例吧!
项目目录。
在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页面。
使用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中填写的参数如果名字相同,那么会多次赋值。
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;
}