带你从零学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的主要内容,如果未能解决你的问题,请参考以下文章

带你从零学ReactNative开发跨平台App开发

带你从零学ReactNative开发跨平台App开发(十三)

带你从零学ReactNative开发跨平台App开发

带你从零学ReactNative开发跨平台App开发

带你从零学ReactNative开发跨平台App开发

带你从零学ReactNative开发跨平台App开发