(1)、可以和后端程序员进行紧密的配合
(2)、让业务前置
(3)、扩展知识面
(1)、实现项目的业务逻辑
(2)、实现数据的增删改查(CRUD)
(3)、Node.js开发服务器的优势?
- Node.js是前端开发人员转向后端开发人员的极佳途径
- 一些公司要求前端工程师掌握Node.js开发
- Node,js生态系统活跃,有大量开源库可以使用
- 前端开发工具大多基于Node.js开发
(4)、用Node.js来代替传统的服务端语言(如Java、 PHP语言等) ,开发服务端的网站应用。客户端和服务器端网站开发流程
3.1、步骤:
(1)引入http模块
(2)创建服务器对象
(3)定义请求和响应
(4)监听端口号
本地机的域名:localhost=== 本地机的IP地址:127.0.0.1(域名和ip地址是一 一对应关系)
const http = require('http')
const app = http.createServer()
app.on('request',(req,res)=>{
res.end('Hello Wolrd')
})
app.listen(9089)
console.log('服务器已启动')
(1)HTTP协议规定了如何从网站服务器传输超文本到本地浏览器。
(2)HTTP协议基于客户端服务器架构工作,是客户端(用户)和服务器(网站)请求和应答的标准。
(3)HTTP协议可以使浏览器更加高效,是网络传输减少。
(4)HTTP协议不仅保证计算机正确快速地传输超文本文档,还确定传输文档中的哪一部分,以及哪部分内容首先显示(如文本先于图形)等。
5.1、请求消息:客户端向服务器发送请求时所携带的数据块。
5.2、响应消息:服务器端响应客户端请求时所携带的数据块。
5.3、客户端向服务器端发送请求的类型
(1)、get请求:在浏览器的地址栏直接输入请求地址或在页面使用超链接,浏览器将默认发送get请求。
(2)、post请求:在标签的method属性中指定为post时,请求方式就是post。
Get请求演示:
客户端:
<!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>
<form action="http://localhost:3000" method="get">
<button type="submit">提交按钮</button>
</form>
</body>
</html>
//1、引入http模块
const http = require('http')
//2、创建一个服务器对象
const server=http.createServer()
//3、给服务器上绑定一个请求事件,服务器接收响应来做出相应的反应应答
server.on('request',(req,res)=>{
console.log('请求方式:',req.method)
res.end('Hello User
')
})
//4、启动服务器,再给服务器一个端口号,监听5000端口上的信息
server.listen(3000)
console.log('服务器已经在3000默认端口上启动')
我们可以看到在终端里以一共有两种请求方式:
分别是:客户端发送请求,form表单的请求为get方式;另一个是服务器端向客户端响应信息发送的默认方式是get方式
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>
<form action="http://localhost:3000" method="get">
<button type="submit">提交按钮</button>
</form>
</body>
</html>
//1、引入http模块
const http = require('http')
//2、创建一个服务器对象
const server=http.createServer()
//3、给服务器上绑定一个请求事件,服务器接收响应来做出相应的反应应答
server.on('request',(req,res)=>{
console.log('请求方式:',req.method)
res.end('Hello User
')
})
//4、启动服务器,再给服务器一个端口号,监听5000端口上的信息
server.listen(3000)
console.log('服务器已经在3000默认端口上启动')
可以看到post也有俩次请求方式:
分别是:客户端发送请求,form表单的请求为post方式;另一个是服务器端向客户端响应信息发送的默认方式是get方式
5.4、get请求和post请求的区别
post请求 | get请求 |
---|---|
post请求的参数包含在请求体中。 | get请求的参数是通过URL进行传递。 |
post请求相对比较安全 | get请求不安全,不能用来传输敏感信息 |
post请求对长度没有限制 | get请求在url中传递的参数是有长度限制的(不同的浏览器限制的长度不同) |
post请求参数不会再浏览器中保留 | get请求参数会被完整的保留在浏览器的历史记录中 |
post请求支持多种编码方式 | get请求使用url编码(百分号编码) |
post请求不可以被主动缓存(cache) | get请求在浏览器中可以被主动缓存(cache) |
post请求在浏览器回退时会再次向服务器提交数据(小缺点,效率比get请求慢,因为要将数据打向服务器再次包发送数据) | get请求在浏览器回退时是无害的(回退就是浏览器左上方那个会退箭头) |
post请求时浏览器会先发送请求头(http header),服务器响应后(状态码100),浏览器会再次发送数据(data),服务器器会给客户端返回状态码200 | get请求时浏览器会把请求头(http header)和数据(data)一起发送出去; |
5.5、服务器收到用不同请求方式发送的请求时,如何分开处理(服务器如何区分get请求和post请求)
方法:通过对请求对象(request)的method属性进行判断,来获取用户的请求方式
//1、引入http模块
const http=require('http')
//2、创建服务器对象
var app=http.createServer()
//3、定义请求和响应
/*回调函数的参数:
req(request):表示请求对象,存放了客户端的所有请求信息
res(response):表示响应对象,服务器端通过该对象向客户端发送响应信息*/
app.on('request',(req,res)=>{
if(req.method=='POST'){
res.end('post')
}else if(req.method=='GET'){
res.end('get')
}
})
//4、监听端口号:指定服务器所使用的端口号
app.listen(9089)
console.log('服务器已启动,工作在9089端口上')
请求方式为get,返回结果为get
请求方式为post,返回结果为post
5.6、根据客户端的请求地址访问不同的内容
方法:通过对请求对象(request)的url属性来获取用户的请求地址
const http=require('http')
var app=http.createServer()
app.on('request',(req,res)=>{
let url=req.url
if(url=='/index'||url=='/'){
res.end('Home Page
')
}else if(url=='/list'){
res.end('List Page
')
}else{
res.end('Not Found
')
}
})
app.listen(8089)
console.log('服务器已启动,工作在8089端口上')
(1)、请求头是请求信息的一部分,是由客户端浏览器自动发送给服务器的
(2)、请求头的详细信息
A、格式:以键值对的方式保存
B、属性:
属性 | 属性说明 |
---|---|
User-Agent | 发送请求的浏览器的类型 |
Accept | 服务器响应消息的格式 |
Accept-Language | 客户端可以接收的语言 |
Accept-Encoding | 客户端可以接收的编码压缩格式 |
Accept-Charset | 可接收的应答的字符集 |
Host | 请求的主机名 |
connection | 连接方式(close 或keepalive) |
const http=require('http')
var app=http.createServer()
app.on('request',(req,res)=>{
const headers = req.headers
console.log(headers)
})
app.listen(8089)
console.log('服务器已启动,工作在8089端口上')
5.8、响应消息
(1)、在响应消息中,对于客户端的每一次请求, 服务器端都要给予响应,在响应的时候我们可以通过状态码告诉客户端此次请求是成功还是失败。状态代码由3位数字组成,表示请求是否被理解或被满足。HTTP响应状态码的第一个数字定义了响应的类别,后面两位没有具体的分类,第1位数字有5种可能的取值。
(2)、状态码
状态码 | 说明 |
---|---|
1** | 请求已接收,需要继续处理 |
2** | 请求已成功被服务器接收、理解 |
3** | 为完成请求,客户端需进一步细化请求 |
4** | 客户端的请求有错误 |
5** | 服务器端出现错误 |
常用状态码:
状态码 | 说明 |
---|---|
200 | 表示请求响应成功 |
302 | 表示请求的资源临时从不同URL响应请求,但请求者应继续使用原有位置来进行以后的请求 |
404 | 请求的服务器资源不存在 |
500 | 服务器程序有语法错误 |
(3)、响应内容的类型(Content-Type)
响应内容的类型 | 说明 |
---|---|
text/plain | 返回纯文本格式的内容 |
text/html | 返回HTML格式 |
text/ CSS | 返回CSS格式 |
application/javascript | 返回JavaScript格式 |
image/jpeg | 返回JPEG图片格式 |
application/json | 返回JSON代码格式 |
const http = require('http')
const server=http.createServer()
server.on('request',(req,res)=>{
res.writeHead(200,{
'content-type':'text/html;charset=utf8'
})
res.end('你好,我是服务器端。
')
})
server.listen(8089)
console.log('服务器已经在8089默认端口上启动')
1.1、get参数是放在浏览器的地址栏中发送的(即请求参数和url绑在一起)
1.2、get参数的获取方式
(1)、通过请求对象(req)的url属性获取客户端请求的URL(req.url)
(2)、使用Node的内置模块url对请求地址进行解析,获取请求参数let { query,pathname } = url.parse(clientURL,true)
const url = require('url')
const http = require('http')
const qs = require('querystringify')
const app = http.createServer()
app.on('request',(req,res)=>{
//1、获取客户端请求url
let clinentURL = req.url
console.log(clinentURL)
//2、解析url
let {query,pathname} = url.parse(clinentURL,true)
console.log('请求参数:',query)
console.log('请求路径:',pathname)
//3、进行请求判断
if(pathname=='index'|| pathname == '/'){
res.writeHead(200,{
'content-type':'text/html;charset=utf8'
})
res.end('hello'
+query.username+'')
}else if(pathname == '/list'){
res.end('List Page
')
}else{
res.end('FOUND
')
}
})
app.listen(8089)
console.log('服务器已经启动,运行在8089端口上')
2.1、post请求参数是放在请求体中,而不是放在url当中
(1)、导入Node的内置模块querystring,将post请求参数转换成对象
(2)、给请求对象(req)注册’data’事件,用于监听参数的传输,将传输的参数读取出来
(3)、给请求对象(req)注册’end’事件,用于监听参数传输完毕,该事件被触发表明参数传递完成就可以对参数进行处理
演示:
服务器:
const url = require('url')
const http = require('http')
const qs = require('querystringify')
const app = http.createServer()
app.on('request',(req,res)=>{
let postParams = '' //用来存储post请求参数
//给req注册data事件,监听参数的传递
req.on('data',(params)=>{ //params表示请求参数,参数的传递是以字符流的方式传递的。
postParams +=params
})
//给req注册’end‘事件,该事件被
req.on('end',()=>{
console.log('获得的参数:',postParams)
let temp = qs.parse(postParams)
console.log('解析后的参数:',temp)
console.log('用户名:',temp.username)
console.log('密码:',temp.pwd)
})
res.end('ok')
})
app.listen(8089)
console.log('服务器已经启动,运行在8089端口上')
客户端:
<!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>
<style>
div{
width: 500px;
margin:100px auto;
}
</style>
<body>
<div>
<form action="http://localhost:8089" method="POST">
<label>
用户名:<input type="text" name="username">
</label>
<br><br><br>
<label>
密 码:<input type="password" name="pwd">
</label>
<br><br>
<button type="reset">取消</button>
<button type="submit">提交</button>
</form>
</div>
</body>
</html>
强调:关于querystring被启用的解决办法,使用querystringify模块,替代 querystring。因为querystringify模块不是node内置模块,所以需要安装指令npm i querystringif
3.1、路由是指客户端请求地址与服务器端程序代码的对应关系。用户在浏览器地址栏中输入不同的请求地址,服务器端会为客户端响应不同的内容。
演示:
const url = require('url')
const http = require('http')
const path = require('path') //用于路径拼接
const fs = require('fs')//用于读取文件
const mime = require('mime')//第三方模块用于数据传输
const server = http.createServer()
server.on('request',(req,res)=>{
//1、获取用户的请求方式
let method = req.method.toLowerCase()
//2、解析用户请求地址
const pathname = url.parse(req.url).pathname
//3、设置响应头的信息
res.writeHead(200,{
'content-type':'text/html;charset=utf8'
})
//4、进行路由
if(method == 'get'){
if(pathname == '/' || pathname == '/index'){
let msg = '欢迎来到首页
'+
'您的请求方式是get
'
res.end(msg)
}else if(pathname == '/list'){
let msg = '欢迎来到列表
'+
'您的请求方式是get
'
res.end(msg)
}else{
res.end('请求不存在')
}
}else if(method == 'post'){
}
})
server.listen(3000)
console.log('服务器已经启动,运行在3000端口上')
3.2、静态资源访问
(1)、静态资源:是指客户端向服务器端请求的资源,服务器端不需要处理,可以直接响应给客户端的资源。
(2)、静态资源的类型:CSS、JavaScript、image文件,以及HTML文件
(3)、动态资源:指的是相同的请求地址可以传递不同的请求参数,得到不同的响应资源
(4)、访问过程:
A、创建一个文件夹用于存放静态资源
B、获取用户的请求路径
C、使用path模块对请求路径进行转换(将请求路径转换成静态资源对应的硬盘路径)
D、使用mime模块获取静态资源的类型
E、使用fs模块读取静态资源文件
F、将读取的静态资源响应给用户
演示:
const http=require('http')
const url=require('url')
const path =require('path')//用于路径的拼接
const fs=require('fs')//用于读取文件
const mime =require('mime')
const server=http.createServer()
server.on('request',(req,res)=>{
//1、获取用户请求路径
let pathname=url.parse(req.url).pathname
pathname = pathname =="/"?'/default.html':pathname//判断用户是否请求了静态资源,三元表达式,地址如果为空,则显示默认页面default.html
//2、将用户的请求路径转换成实际的服务器的硬盘路径
let realPath = path.join(__dirname,'public'+pathname)
//3、通过mime模块根据路径得到相应的资源类型
let type = mime.getType(realPath)
//4、读取文件
fs.readFile(realPath,(err,result)=>{
if(err!=null){//如果文件读取失败
res.writeHead(404,{
'content-type':'text/html;charset=utf8'
})
res.end('文件读取失败')
}else{
res.writeHead(200,{
'content-type':type
})
res.end(result)
}
})
})
server.listen(4000)
console.log('服务器已启动,服务器运行在4000端口上...')
defult.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>
<h1>我是首页</h1>
</body>
</html>