1.创建wab服务器
//用于创建网站服务器的模块 const http = require('http'); //app对象就是网站服务器对象 const app = http.createServer(); //当客户端有请求来的时候 app.on('request',(req,res) => { res.end('<h2>Hello server</h2>'); }) //监听端口 app.listen(3000); console.log("网站服务器启动成功");
2.http协议
2.1HTTP协议的概念
超文本传输协议(英文:Hyper Text Transfer Protocol,缩写HTTP)规定了如何从网站服务器传输超文本到本地浏览器,它基于客户端服务器架构工作,是客户端(用户)和服务器端(网站)请求和应答的标准.
2.2 报文
在HTTP请求和响应的过程中传递的数据块就叫报文,包括要传送的数据和一些附加信息,并且要遵守规定好的格式.
2.3 请求报文
1.请求方式(Request Method)
.get 请求数据
.post 发送数据,更安全
2.请求地址(Request URL)
app.on('request',(req,res) => { req.headers //获取请求报文 req.url //获取请求地址 req.method //获取请求方法 })
req.headers 获取请求报文信息
2.获取请求地址 req.url
//获取请求地址 console.log(req.url); if(req.url == '/index' || req.url == '/'){ res.end('Welcome to homepage'); }else if(req.url == '/list'){ res.end('Welcome to listpage') }else{ res.end('Not found') }
3.req.method 获取请求方式
//req.method console.log(req.method) if(req.method == 'POST'){ res.end('post') }else if(req.method == 'GET'){ res.end('get') }
2.4 响应报文
1.HTTP状态码
1.200请求成功
2.404请求的资源没有被找到
3.500服务器端错误
4.400客户端请求有语法错误
//当客户端有请求来的时候 app.on('request',(req,res) => { //给客户端相应的状态码和响应内容信息 res.writeHead(200) })
2.响应内容的类型
1.text/html
2.text/css
3.application/javascript
4.image/jpeg
5.application/json
6.text/plain //纯文本
//当客户端有请求来的时候 app.on('request',(req,res) => { //给客户端相应的状态码和响应内容信息 res.writeHead(200,{ 'content-type':'text/html' }) })
响应的内容信息类型,需要和返回的内容类型保持一致,如果你希望在页面中展示的是HTML内容,但是在响应信息中的类型填的是“text/plain”纯文本,那么在页面中显示的就是没有编译的文字信息
如果想要在浏览器中想要有h1的大字样式,在类型中需要填“text/html”,这样页面中的效果就如下图所示了:
当我们把响应信息的内容改成了中文以后
if(req.url == '/index' || req.url == '/'){ res.end('<h1>欢迎来到首页</h1>'); }
会发现页面中的显示内容变成了乱码:
这是因为我们的页面编码需要指定为utf8,在响应信息头部指定一下就好了
//给客户端相应的状态码和响应内容信息 res.writeHead(200,{ 'content-type':'text/html;charset=utf8' })
3.HTTP请求与响应处理
3.1请求参数
客户端向服务器端发送请求时,有时需要携带一些客户信息,客户信息需要通过请求参数的形式传递到服务器端,比如登录操作
3.2 GET参数
1.参数被放置在浏览器地址栏中,例如:http://localhost:3000?name=zhangsan&age=20
// 用于处理url地址 const url = require('url');
解析请求地址:
//获取请求地址 console.log(req.url); //第一个参数:要解析的url地址 //第二个参数:将查询参数解析成对象形式 let {query,pathname} = url.parse(req.url,true);
3.3 POST参数
1.参数被放置在请求体中进行传输
2.获取POST参数需要使用data事件和end事件
3.使用querystring系统模块将参数转换为对象格式
//导入系统模块querystring,用于将HTTP参数转换为对象格式 const querystring = require('querystring'); //app对象就是网站服务器对象 const app = http.createServer(); //当客户端有请求来的时候 app.on('request',(req,res) => { let postdata = ''; //监听参数传输事件 req.on('data',(chunk) => postdata += chunk); //监听参数传输完毕事件 req.on('end',() => { console.log(querystring.parse(postdata)) }) res.end('<h1>You are welcome</h1>'); })
3.4 路由
路由是指客户端请求地址与服务器端程序代码的对应关系。简单的说,就是请求什么响应什么。
//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 = url.parse(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'){ if(pathname == '/' || pathname == '/index'){ res.end('欢迎来到首页') }else if(pathname == '/list'){ res.end('欢迎来到列表页') }else{ res.end('您访问的页面走丢了') } } }) //监听端口 app.listen(3000); console.log("网站服务器启动成功");
3.5 静态资源
服务器端不需要处理,可以直接响应给客户端的资源就是静态资源,例如CSS,Javascript,image文件。
静态文件读取:
const http = require('http'); const url = require('url'); const path = require('path'); const fs = require('fs');//读取文件 const app = http.createServer(); app.on('request',(req,res) => { //给客户端相应的状态码和响应内容信息 res.writeHead(200,{ 'content-type':'text/html;charset=utf8' }) //获取用户的请求路径 let {pathname} = url.parse(req.url); console.log(pathname)///default.html //获取当前文件所在的绝对路径:__dirname //将用户的请求路径转换为实际的服务器硬盘路径 var realPath = path.join(__dirname,'public' + pathname) console.log("realPath",realPath)//realPath D:\work相关\myspace\mystudy\node_study\day04_server\static\public\default.html //读取文件 fs.readFile(realPath,(error,result) => { //如果文件读取失败 if(error != null){ res.writeHead(404,{ 'content-type':'text/html;charset=utf8' }) res.end('文件读取失败'); return; } res.end(result) }) }) //监听端口 app.listen(3000); console.log("网站服务器启动成功");
当用户没有写具体的访问页面时,默认让他访问default.html 文件
pathname = pathname=='/'?'/default.html':pathname;
当前用户访问时,请求出错时返回了,用户访问的资源的类型,但是请求成功时,并响应报文中并没有返回文件的类型,是存在一定的安全隐患的
通过安装一个插件mime,来获得当前请求资源的类型,并将其返回在响应报文的头部
npm install mime
let type = mime.getType(realPath);
res.writeHead(200,{ 'content-type':type })
这样之后,响应报文的头部就会出现访问资源的类型
3.6 动态资源
相同的请求地址不同的响应资源,这种资源就是动态资源