创建web服务器和http协议
1.服务端基础
1.1网站组成
网站应用程序分为两部分:客户端和服务端;
客户端:在浏览器运行的部分,就是用户看到并与之交互的界面程序,使用html和css和js构建;
服务端:在服务器中运行的部分,负责存储数据和处理应用逻辑;
1.2node服务器
能够提供网站访问服务的机器就是网站服务器,它能接收客户端的请求,能够对请求作出响应;
1.3 IP地址
互联网中设备的唯一标识;
IP是Internet Protocol Address 的简写,代表互联网协议地址;
1.4域名
由于IP地址难于记忆,所以产生了域名的概念,域名就是上网所使用的的网址;
虽然在地址栏里输入的是网址,但是最终还会将域名转换为ip地址才能访问到指定的网站服务器;
1.5端口
使用端口区分不同的服务,它是一些具有一定范围的数字,范围是0-65535,每一个向外界提供服务的软件,都要占用一个端口;
1.6URL
统一资源定位符,又叫URL(Uniform Resource Locator),是专为标识Internet网上资源位置而设的一种编址方式,平时所说的网页地址就是URL;
URL的组成
传输协议://服务器IP或域名:端口/资源所在位置标识;
2.创建web服务器
//引用系统模块http
const http = require('http');
//声明一个变量用来作为网站服务对象
const app = http.createServer();
//通过事件监听的方式,监听用户发来的请求
//当客户有请求的时候 ,就会触发这个事件,来执行这个事件处理函数,req是请求对象,res是响应对象
app.on('request',(req,res) => {
//收到请求后,响应
res.end('成功了');
})
//监听端口,端口可以随意设置,只要不被占用就可以
app.listen(2001);
//打印这句话为了能很好的看到服务器是否启动成功
console.log('服务器启动成功');
3.http协议
超文本传输协议(英文:HyperText Transfer Protocol
,缩写:http
)规定了如何从网站服务器传输超文本到本地浏览器,它基于客户端服务器架构工作,是客户端和服务器端请求和应答的标准;
3.1报文和请求报文
**报文:**在http请求和响应的过程中传递的数据就是报文,包括要传送的数据和一些附加信息,并且要遵守规定好的格式;
请求报文
1.请求方式
(1) GET 请求数据
(2)POST 发送数据
2.1请求地址
(1).获取请求报文 req.headers
(2).获取请求地址 req.url
(3).获取请求方式 req.methed
//引入http模块
const http = require('http');
//引入内置模块url
const url = require('url');
//创建web服务器
const app = http.createServer();
app.on('request',(req,res) =>{
//1.获取请求的方式 req.methed
// console.log(req.method);//GET或者POST
//2.获取请求地址req.url
//console.log(req.url); //打印的就是地址栏端口号2002后边的数据
//3.获取请求报文
//console.log(req.headers)
if(req.method == 'POST'){
//如果是post方式,响应一个结果
res.end('post');
}else if(req.method == 'GET'){
//如果是get方式,响应一个结果
res.end('get');
}
})
app.listen(2002);
console.log('服务器启动成功');
3.2响应报文
1.http状态码
(1).200:请求成功;
(2).404:请求资源没有找到;
(3).500: 服务端错误;
(4).400: 客户端请求语法错误;
2.内容类型
text/html
text/css
application/javascript
image/jpeg
application/json
app.on('request', (req, res) => {
// 设置响应报文
res.writeHead(200, {
'Content-Type': 'text/html;charset=utf8‘
});
});
4.http请求和响应处理
//地址栏里边http://localhost:3000/?name=zhangsan&age=20
//打印通过系统url模块下的parse方法将url路径的各个部分解析出来并返回对象
//true表示将参数解析为对象格式
console.log(url.parse(req.url,true))
//结果为
Url {
protocol: null,
slashes: null,
auth: null,
host: null,
port: null,
hostname: null,
hash: null,
search: '?name=zhangsan&age=20',
//获取get请求的name和age
query: [Object: null prototype] { name: 'zhangsan', age: '20' },
//pathname为要请求跳转的页面,此处没有写
pathname: '/',
path: '/?name=zhangsan&age=20',
href: '/?name=zhangsan&age=20' }
1.GET请求参数
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);
2.POST请求参数
- 参数被放置在请求体中进行传输
- 获取POST参数需要使用data事件和end事件
- 使用
querystring
系统模块将参数转换为对象格式
//html页面的form表单 表单里边填写username:123456 ;pwd:123123
<form method="post" action="http://localhost:3000">
<input type="text" name="username">
<input type="password" name="pwd">
<input type="submit">
</form>
//js模块
//用于创建网站服务器的模块
const http = require('http');
//app对象就是网站服务对象
const app = http.createServer();
//处理请求参数模块
const querystring = require('querystring');
//当客户端有请求来的时候
app.on('request',(req,res)=>{
//post参数是通过事件的方式接收的
//data当请求参数传递的时候触发data事件
//end当参数传递完成的时候触发end事件
//声明一个变量用于拼接接收到的数据
let postParams = "";
req.on('data',params => {
postParams += params;
});
//参数传递完成时,打印在控制台
req.on('end',()=>{
// 以对象模式打印出来 { username: '123456', pwd: '123123' }
console.log(querystring.parse(postParams));
})
// 页面给的回应
res.end('好了好了');
})
//监听端口
app.listen(3000);
console.log('网站服务器启动成功');
3.路由模块
//1.引入系统模块
//2.创建网站服务器
//3.为网站服务器对象添加请求事件
//4.实现路由功能
// 1.获取客户端的请求方式
// 2.获取客户端的请求地址
const http = require('http');
const url = require('url');
const app = http.createServer();
//处理请求参数模块
const querystring = require('querystring');
//当用户发送请求时
app.on('request', (req, res) => {
//获取请求方式
const method = req.method();
//获取请求地址
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') {
//post参数是通过事件的方式接收的
//data当请求参数传递的时候触发data事件
//end当参数传递完成的时候触发end事件
//声明一个变量用于拼接接收到的数据
let postParams = "";
req.on('data', params => {
postParams += params;
});
//参数传递完成时,打印在控制台
req.on('end', () => {
// 以对象模式打印出来
console.log(querystring.parse(postParams));
})
// 页面给的回应
res.end('haolehaole');
}
})
app.listen(2000);
console.log('服务器启动成功');
5.http请求头和响应头含义
Accept
:告诉服务器,客户端支持的数据类型;
Accept-Charset
:告诉服务器,客户端采用的编码;
Accept-Encoding
:告诉服务器,客户机支持的数据压缩格式;
Accept-Language
:告诉服务器,客户机的语言环境;
Host
:客户机通过这个头告诉服务器,想访问的主机名。
If-Modified-Since
:客户机通过这个头告诉服务器,资源的缓存时间。
Referer
:客户机通过这个头告诉服务器,它是从哪个资源来访问服务器的。(一般用于防盗链)
User-Agent
:客户机通过这个头告诉服务器,客户机的软件环境。
Cookie
:客户机通过这个头告诉服务器,可以向服务器带数据。
Connection
:客户机通过这个头告诉服务器,请求完后是关闭还是保持链接。
Date
:客户机通过这个头告诉服务器,客户机当前请求时间。
http请求中常用的响应头的含义:
Location
:这个头配合302状态码使用,告诉用户端找谁。
Server
:服务器通过这个头,告诉浏览器服务器的类型
Content-Encoding
:服务器通过这个头,告诉浏览器数据采用的压缩格式。
Content-Length
:服务器通过这个头,告诉浏览器回送数据的长度。
Content-Language
:服务器通过这个头,告诉服务器的语言环境。
Content-Type
:服务器通过这个头,回送数据的类型
Last-Modified
:服务器通过这个头,告诉浏览器当前资源的缓存时间。
Refresh
:服务器通过这个头,告诉浏览器隔多长时间刷新一次。
Content-Disposition
:服务器通过这个头,告诉浏览器以下载的方式打开数据。
Transfer-Encoding
:服务器通过这个头,告诉浏览器数据的传送格式。
ETag
:与缓存相关的头。
Expires
:服务器通过这个头,告诉浏览器把回送的数据缓存多长时间。-1或0不缓存。
Cache-Control
和Pragma
:服务器通过这个头,也可以控制浏览器不缓存数据。
Connection
:服务器通过这个头,响应完是保持链接还是关闭链接。Date:告诉客户机,返回响应的时间。