我的前端自学 node.js基础(二)

(一)服务器端基础概念
1 .URL
URL的组成:
传输协议://服务器IP或域名:端口/资源所在位置标识
http://astro.sina.com.cn/focus/leo/
http:超文本传输协议,提供了一种发布和接收HTML页面的方法
2 .本机域名
localhost 127.0.0.1

(二)创建web服务器
创建web服务器要用到系统模块http,使用系统模块http下面的createServer方法,返回一个服务器对象,
为服务器对象绑定事件处理,对请求做出响应,最后监听服务器端口。

// 引入http系统模块
const http = require("http");
// 创建服务器对象
let app = http.createServer();
// 添加事件request
app.on("request", (req, res) => {
	// 对请求做出响应   参数 req: 请求对象   res: 响应
	res.end("<h1>Welcome!</h1>");
})
// 监听端口
app.listen(3000);
// 访问: localhost:3000

(三) HTTP协议
1 .报文:在http请求和响应的过程中传递的数据库就叫报文。包括要传递的数据和一些附加信息,并且要遵守规定好的格式。

请求报文:
①请求方式:
GET 请求数据
POST 响应数据

获取请求方式:通过req请求对象里的method方法,req.method
最常见的get请求就是从地址栏输入地址的方式,相对而言,post请求比get请求要安全,所以post请求方式一般用于提交表单。

const http = require("http");
let app = http.createServer();
app.on("request", (req, res) => {
	// 获取请求方式
	let method = req.method.toLowerCase();
	if (method == "get") {
		res.end("get");
	} else {
		res.end("post");
	}
})
app.listen(3000);

获取客户端的请求地址:通过请求对象的url方法,req.url

const http = require("http");
let app = http.createServer();
app.on("request", (req, res) => {
	let method = req.method.toLowerCase();
	// 获取请求信息
	let url = req.url;
	if (method == "get") {
	// 如果客户端输入地址为/index或者为空
		if (url == "/index" || url == "/") {
			res.end("Welcome to indexPage");
		} else if(url == "/list") {
		res.end("Welcome to listPage")
		} else {
			res.end("NOT FOUND");
		}
	} else {
		// POST
	}
})

获取请求报文 :req.headers
获取请求报文属性:如获取请求报文的accpet :req.headers[‘accept’]

②响应报文
HTTP状态码,用于响应给客户端请求的结果
200 请求成功
404 请求资源未找到
500 服务器端错误
400 客户端请求语法错误

HTTP状态码通过res.writeHead()响应给客户端

内容类型:
res.writeHead()第一个参数为HTTP状态码,第二个参数为内容类型
text/plain 纯文本
text/html html文件
text/css css文件
application/javascript JS文件
image/jpeg 图片文件
application/json json文件

res.writeHead(200, {
	"content-type": "text/html;charset=utf8"
})

2 .请求参数
客户端向服务端发送请求时,通常要携带一些客户信息,客户信息要通过请求参数的形式传递给服务器,比如登录操作。请求参数分为GET请求参数和POST请求参数。
get请求参数:
http://localhost:3000/list?uname=admin&password=123456
问号后面的信息就为请求参数信息。

获取请求参数:
由于请求参数信息包含在url里面,我们可以通过req.url获取,再通过系统模块url下面的url.parse(req.url, true)方法进行处理,处理后的结果包含了query对象(以键值对形式存储的请求参数信息)和pathname(不包含请求信息的请求地址)。

const http = require("http");
const url = require("url");
let app = http.createServer();
app.on("request", (req, res) => {
	res.writeHead(200, {
		"content-type": "text/html; charset=utf8"
	})
	let {query, pathname} = url.parse(req.url, true);
	// query: { name: admin, password: 123456 }
	let method = req.method.toLowerCase();
	if (method == "get") {
		if (pathname == "/" || pathname == "/index") {
			res.end("欢迎来到首页");
		} else if(pathname == "/list") {
			res.end("欢迎来到列表页");
		} else {
			res.end("页面没有找到");
		}
	} else {
		// POST
	}
})

post请求参数:
post请求常用来提交表单

<form action="http://localhost:3000" method="post">
	账号 <input type="text" placeholder="请输入密码"><br />
	密码 <input type="password"><br />
	<input type="submit" value="提交">
</form>

post请求参数被放置在请求报文的Form Data中,和get请求的格式是一样的
uname=admin&password=123456
由于post请求参数理论上讲长度是无限的,服务器接收post请求参数不是一次性就接收完的,post请求参数通过data和end事件来分次接收。
在接收post请求之前声明一个变量为空字符串,在触发data事件时,我们将变量进行拼接,在触发end事件时输出拼接完成的变量
这样,就成功获取了客户端的post请求参数:uname=admin&password=123456,下面将获取的结果转换为键值对格式,注意,post请求参数不能使用url模块来处理,node提供了专门用于处理post请求参数的querystring模块中的parse方法。

// const querystring = require("qureystring");
app.on("request", (req, res) => {
	let postParams = "";
	req.on("data", params => { postParams += params });
	req.on("end", () => { console.log(querystring.parse(postParams)) });
	res.end("ok");
})

3 .路由
路由是指客户端请求代码与服务器端程序代码的对应关系,简单来说,就说服务器端为响应客户端请求编写的处理逻辑。如以上,我们在request事件里编写的用于判断请求方式和请求地址,响应相应的信息的代码。

4 .静态资源访问
服务器不需要处理,可以直接相应给客户端的资源,就是静态资源,如image,css,JS

// 1.引入http模块
const http = require("http");
const url = require("url");
const path = require("path");
const fs = require("fs");
const mime = require("mime");
// 2 .创建服务器对象
let app = http.createServer();

// 3.请求和相应事件处理
app.on("request", (req, res) => {
	// 5.获取客户端请求地址(引入url模块)
	let pathname = url.parse(req.url).pathname;
	// 11 .处理客户端请求地址为空
	pathname = pathname == "/" ? "/index.html" : pathname;
	// 6 .拼接请求地址,对应服务器端物理地址(引入path模块)
	let realpath = path.join(__dirname, "static", "public" + pathname);
	// 7. 读取对应物理路径文件(引入fs模块)
	// 10. 指定相应报文的内容类型(引入mime模块,并使用mime.getType方法自动获取对应类型)
	let type = mime.getType(realpath);
	fs.readFile(realpath, (err, doc) => {
		// 8. 如果读取失败,抛出错误
		if (err != null) {
			res.writeHead(404, {
				"content-type": "text/html;charset=utf8"
			});
			res.end("文件未找到");	
		}
		// 9.如果读取成功,指定相应报文的内容类型并响应相应内容
		res.writeHead(200, {
			"content-type": type
		});
		res.end(doc);
	})
})
// 4.监听端口
app.listen(3000);

5 .promise
promise构造函数是为了解决回调地狱的问题,它是异步编程语法上的改进,可以让异步API的执行和结果的处理分离,并且可以链式调用。

let promise = new Promise((resolve, reject) => {
	// 第一个参数resolve指的是程序执行成功执行的函数
	// 第二个参数reject指的是执行失败执行的函数
	// 当程序执行完毕后,链式调用then方法来接收执行成功的结果,调用catch方法接收执行失败的错误信息
}).then().catch();

promise是如何解决回调地狱的:
当前需求为依次读取指定目录下的三个文件,用回调函数写法:

const fs = require("fs");
fs.readFile("./1.txt", "utf8", (doc) => {
	console.log(doc);
	fs.readFile("./2.txt", "utf8", (result) => {
		console.log(result);
		fs.readFile("./3.txt", "utf8", (tel) => {
		console.log(tel);
		})
	})
})

使用promise改进的写法:

const fs = require("fs");
function first() {
    return new Promise((resolve, reject) => {
        fs.readFile("./1.txt", "utf8", (err, doc) => {
            resolve(doc);
        })
    })
}
function second() {
    return new Promise((resolve, reject) => {
        fs.readFile("./2.txt", "utf8", (err, doc) => {
            resolve(doc);
        })
    })
}
function third() {
    return new Promise((resolve, reject) => {
        fs.readFile("./3.txt", "utf8", (err, doc) => {
            resolve(doc);
        })
    })
}
first().then((doc) => {
    console.log(doc)
    return second();
}).then((doc) => {
    console.log(doc)
    return third();
}).then((doc) => {
    console.log(doc)
})

异步函数:异步函数是异步编程语法的终极解决方案(ES7),它可以将异步代码写成同步的形式,使结构更清晰的前提下大大简化代码。

在普通函数前面加上 async关键字,普通函数就成了异步函数,它会将函数内部的代码包装成一个promise对象并返回,在异步函数中,我们可以在promise对象前面使用await关键字,它可以暂停异步代码的执行过程,等待异步函数返回结果后再向下执行。

Node.js中的回调函数,根据约定具有统一形式,(err, value)=>{},
因此,我们可以用统一的办法,将接受这种回调函数作为参数的函数,转换为返回promise的函数,node提供了util模块下的promisify方法,用以改造现有node.js中的异步API,方便我们快捷的把原来的异步回调方法改成返回 Promise 实例的方法
使用异步函数改造以上依次读取三个文件的代码如下:

const fs = require("fs");
const util = require("util");
const readFile = util.promisify(fs.readFile);
async function run() {
	let first = await readFile("./1.txt", "utf8");
    let second = await readFile("./2.txt", "utf8");
    let third = await readFile("./3.txt", "utf8");
    console.log(first);
    console.log(second);
    console.log(third); 
}
run();
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值