带你从零学Node.js
Posted 小hu同学
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了带你从零学Node.js相关的知识,希望对你有一定的参考价值。
本篇文章是接着上一篇带你从零学Node.js(一)来写的,连着一起看更连贯喔!
1、服务器端基础概念
1.1 URL
URL 翻译成中文叫统一资源定位符,是专为标识Internet网上资源位置而设置的一种编址方式,我们平常所说的网页地址指的就是URL。
URL的组成
传输协议
://服务器IP或域名端口/资源所在的位置标识
http
://www.baidu.com/new/20210530/1234.html
http:超文本传输协议。提供了一种发布和接收HTML页面的方法
端口: 网站默认的是80端口,所以我们平常在输入的时候,就没有输入80这个端口号
1.2 开发过程中客户端和服务器端说明
在开发阶段,客户端和服务器端可以使用同一台电脑,即客户端(浏览器)
,服务器端(Node)
本机域名:localhost
本地IP:127.0.0.1
2、创建web服务器
2.1 创建web服务器
示例代码
//引用系统模块
const http = require('http');
//创建web服务器
const app = http.createServer();
//当客户端发送请求的时候
app.on('request',(req,res) =>{//req是请求对象,res是响应对象
//响应
res.send(`<h1>123</h1>`)
})
//监听端口号
app.listen(3000);
console.log('服务器已经启动,请访问localhost:3000')
//在浏览器输入localhost:3000就可以访问了,这里的3000也可以改成其他的端口号
3、HTTP协议
3.1 HTTP协议的概念
超文本传输协议(因为缩写:HTTP),规定了如何从网站服务器传输超文本到本地浏览器,它基于客户端服务器架构工作,是客户端(用户)和服务器端(网站)请求和响应的标准
3.2 报文
在HTTP请求和响应的过程中传递的数据块就叫报文,敖阔传输的数据和一些附加信息,并且要遵守规定好的格式。
报文信息的查看
3.3 请求报文(GET/POST)
1、请求方式(Request Methed)
- GET (请求数据 ,默认的是GET请求)
- POST (发送数据)
获取get 的请求方式req.method
//当客户端发送请求的时候
app.on('request',(req,res) =>{//req是请求对象,res是响应对象
//获取get请求方式 req.method
console.log(req.method)
//响应
res.send(`<h1>123</h1>`)
})
如何发送POST请求
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!--
method:指定当前表单的提交方式是为post 还是为get
action:指定当前提交的地址
-->
<form method="post" action="http://location:3000">
<input type="submit" name=""></input>
</form>
</body>
</html>
GET请求和POST请求的一个判断
//当客户端发送请求的时候
app.on('request',(req,res) =>{//req是请求对象,res是响应对象
//获取get请求方式 req.method
console.log(req.method)
//要是请求是为POST请求就执行下面这句
if( req.method == 'POST'){
res.send('post')
}//要是请求是为GET请求,就执行下面这句
else if( req.method == 'GET'){
//响应
res.send('get')
}
})
2、请求地址(Request URL)
app.on('request', (req, res) => {
req.headers // 获取请求报文
req.url // 获取请求地址
req.method // 获取请求方法
});
3.4 响应报文(状态码)
1、HTTP状态码
200请求成功
404请求的资源没有被找到
500服务器端错误
400客户端请求有语法错误
代码示例
app.on('request',(req,res) =>{//req是请求对象,res是响应对象
//设置响应报文
res.writeHead(500);
}
2、内容类型
text/html
text/css
application/javascript
image/jpg
application/json
代码示例
app.on('request',(req,res) =>{//req是请求对象,res是响应对象
//设置响应报文
res.writeHead(200,{
//charset 设置为utf8的格式
'content-type':'text/html;charset=utf8'
});
}
4、HTTP请求与响应原理
4.1 请求参数
客户端向服务器端发送请求的时候,有时需要携带一些客户信息,客户信息需要通过请求参数的形式传递到服务器端,比如登录操作
4.2 GET请求参数
- 参数被放置在浏览器地址栏中,例如:http://localhost/
?name=xiaohu&age=18
- 参数获取需要借助系统模块url,url模块用来处理url地址
代码示例
const http = require('http');
// 导入url系统模块 用于处理url地址
const url = require('url');
const app = http.createServer();
app.on('request', (req, res) => {
// 将url路径的各个部分解析出来并返回对象
// true 代表将参数解析为对象格式
let {query} = url.parse(req.url, true);
console.log(query);
});
app.listen(3000);
4.3 POST请求参数
- 参数被放置在请求体中进行传输
- 获取POST参数需要使用data事件和end事件
- 使用querystring系统模块将参数转换为对象格式
代码示例
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!--
method:指定当前表单的提交方式是为post 还是为get
action:指定当前提交的地址-->
<form method="post" action="http://location:3000">
<!-- 给这两个input框分别一个name值-->
<input type="text" name="username"></input>
<input type="password" name="username"></input>
<input type="submit" name=""></input>
</form>
</body>
</html>
服务端 JS
//创建http网站服务器模块
const http = require('http');
//app对象就是服务器对象
const app = http.createServer();
//处理请求参数模块
const querstring = require('querstring');
//当客户端请求过来时
app.on('request',(req,res)=>{
//post参数是通过事件的方式接受的
//data 当请求参数传递的时候触发data事件
//end 当参数传递完成的时候触发end事件
let xiaohu = '';
//params 就是当前传递过来的参数
req.on('data',params=>{
xiaohu +=params;
});
req.on('end',()=>{
console.log(querstring.parse(xiaohu));
});
//页面上响应一个数据
res.end('ok')
});
//监听端口号
app.listen(3000);
console.log('启动成功');
4.4 路由功能
http://localhost:3000/index.html
http://localhost:3000/admin.html
路由是指客户端请求地址与服务器端程序代码的对应关系,就是说请求什么就响应什么。
示例代码
//1.引入系统模块HTTP
//2.创建网站服务器
//3.为网站服务器对象添加请求事件
//4.实现路由功能
// 1.获取客户端的请求方式
// 2.获取客户端的请求地址
const http = require('http');
const url = require('url');
const app = http.createServer();
app.on('request',(req,res)=>{
//获取请求方式
const method = req.method.toLowerCase();
//获取请求地址
const pathname = URLSearchParams(req.url).pathname;
//指定响应头
res.writeHead(200,{
'content-type':'text/html;charset = utf8'
});
//判断请求地址来响应不同的内容
if(method == 'get'){
if(pathname == '/' || pathname == '/index'){
res.end('欢迎来到首页')
}else if(pathname == '/list'){
res.end('欢迎来到子页面')
}else{
res.end('您访问的页面不存在')
}
}else if(method == 'post'){
}
})
app.listen(6666);
console.log('启动成功 localhost:6666');
4.5 静态资源
静态资源
就是服务器端不需要处理,可以直接响应给客户端的资源就是静态资源,例如CSS、JavaScript、image文件
例如:http://www.baidu.com/images/logo.png
4.5.1 实现静态资源的访问功能
首先我们创建了静态的资源文件
然后在public 同级目录下创建一个app.js文件
const http = require('http');
const url = require('url');
const path = require('path');
const fs = require('fs');
//使用npm install mime 下载模块
const mime = require('mime');
const app = http.createServer();
app.on('request',(req,res) =>{
//获取用户的请求路径
let pathname = url.parse(req.url).pathname;
//给服务器一个判断当 / 的时候,响应的是某一个页面
pathname = pathname == '/' ? '/default.html' : pathname;
//将用户的请求路径转换为实际的服务器硬盘路径
let realPath = path.join(__dirname,'public'+pathname);
//使用mime下面的getType方法,将路径传递进去,可以根据资源的路径来判断文件的类型
let type = mime.getType(realPath)
//读取文件
fs.readFile(realPath,(error,result)=>{
//如果文件读取失败
if(error !=null){
//指定文件编码,以及响应编码
res.writeHead(404,{
'content-type':'text/html;charset=utf8'
})
res.end('文件读取失败')
return;
}
//执行文件响应成功的时候的状态码为200
res.writeHead(200,{
//在请求静态资源的过程中有许多文件,有css,js,html
//根本不知道请求的文件类型,无法写成固定的文件类型
'content-type':type
})
res.end(result)
});
});
app.listen(3030);
console.log('服务器启动成功');
4.6 动态资源
动态资源
是相同的请求地址不同的响应资源,这种资源就是动态资源
http://www.baidu.com/int?id=1
http://www.baidu.com/int?id=2
5、Node.js异步编程
5.1 同步API,异步API
同步API:只有当前API执行完成后,才能继续执行下一个API
示例代码
console.log('a');
console.log('b');
异步API:当前的API执行不会阻塞后续代码的执行
示例代码
console.log('a');
setTimout(
() =>{console.log('b');
},3000)
console.log('c')
//使用setTimout 开启定时器后,不会阻塞任务的执行
//输出结果为 a c b
5.2 同步API,异步API的区别(获取返回值)
同步API可以从返回值中拿到API执行的结果,但是异步API是不可以的
示例代码
// 同步
function sum (n1, n2) {
return n1 + n2;
}
const result = sum (40, 20);
// 异步
function getMsg () {
setTimeout(function () {
return { msg: 'Hello Node.js' }
}, 2000);
}
const msg = getMsg ();
console.log(msg);
//输出结果为 undefined
//原因: 当我们执行getMsg的时候,程序不会等着我们执行完setTimeout,
//它会自动return出去,给到msg 最后打印出来的就是undefined
那异步函数怎么拿呢?回调函数来获取
5.3 回调函数
什么是回调函数?就是自己定义函数让别人去调用
下面代码是回调函数的一种表现形式
// getData函数定义
//callback 是变量的名字
function getData (callback) {}
// getData函数调用
getData (() => {});
示例代码:
function getData(callback){
//这个callback可以传递给实参n ,这样在匿名函数里面就可以拿到传递的参数了
callback('123456')
}
//定义一个实参,去打印出来
getData(function(n){
console.log('callback函数被调用了');
console.log(n);
})
我们回到之前的那个问题,使用回调函数的方式去进行修改代码
// 异步
//传递一个callback形参
function getMsg (callback) {
setTimeout(function () {
callback({
msg: 'Hello Node.js'
})
}, 2000);
}
//使用data实参去接收
getmsg(function(data){
console.log(data);
})
//现在去执行代码,打印出来的就是一个对象了,不会是undefined了
5.4 同步API,异步API的区别(代码执行顺序)
同步API从上到下依次执行,前面代码会阻塞后面代码的执行
示例代码:
for (var i = 0; i < 10; i++) {
console.log(i);
}
console.log('for循环后面的代码');
输出结果:
异步API不会等待API执行完成后在向下执行代码
示例代码:
console.log('代码开始执行');
setTimeout(() => { console.log('2秒后执行的代码')}, 2000);
setTimeout(() => { console.log('"0秒"后执行的代码')}, 0);
console.log(以上是关于带你从零学Node.js的主要内容,如果未能解决你的问题,请参考以下文章