URL的概念
统一资源定位符,又叫URL(Uniform Resource Locator),是专为标识Internet网上资源位置而设的一种编址方式,我们平时所说的网页地址指的即是URL。
URL的组成
传输协议://服务器IP或域名:端口/资源所在位置标识
例如:http://www.itcast.cn/news/20181018/09152238514.html
没写端口的时候默认为80端口
http:超文本传输协议,提供了一种发布和接收HTML页面的方法。
本机域名与本地Ip
本机域名:localhost
本地IP :127.0.0.1
创建web服务器
//创建网站服务器
//需要依赖http模块
const http = require('http');
//进行服务器创建 返回值是网站服务器对象
const app = http.createServer();
//为网站服务器添加请求事件
//当客户端有请求来的时候
app.on('request', (req, res) => {
//req请求对象 res响应对象
res.end('<h2>hello user</h2>');
});
//服务器创建好之后 要监听端口
app.listen(3000);
console.log('网站服务器启动成功');
//要先用Node命令执行这个文件
//浏览器输入localhost:3000
//目前这个地步输出的是 <h2>hello user</h2>
HTTP协议
HTTP协议的概念
超文本传输协议(英文:HyperText Transfer Protocol,缩写:HTTP)规定了如何从网站服务器传输超文本到本地浏览器,它基于客户端服务器架构工作,是客户端(用户)和服务器端(网站)请求和应答的标准。
客户端与服务器端沟通的规定 规定客户端与服务端如何请求与应答
报文的概念
在HTTP请求和响应的过程中传递的数据块就叫报文,包括要传送的数据和一些附加信息,并且要遵守规定好的格式。
请求报文
请求方式分为两种:
GET 请求数据
POST 发送数据
获取请求报文信息的方式: req.headers
//创建网站服务器
//需要依赖http模块
const http = require('http');
//进行服务器创建 返回值是网站服务器对象
const app = http.createServer();
//为网站服务器添加请求事件
//当客户端有请求来的时候
app.on('request', (req, res) => {
//获取请求报文信息 req.headers
console.log(req.headers);
console.log(req.headers['accept']);
});
//服务器创建好之后 要监听端口
app.listen(3000);
console.log('网站服务器启动成功');
//要先用Node命令执行这个文件
//目前这个地步输出的是 <h2>hello user</h2>
获取请求地址的方式req.url:(这个会包含?后的部分)
//创建网站服务器
//需要依赖http模块
const http = require('http');
//进行服务器创建 返回值是网站服务器对象
const app = http.createServer();
//为网站服务器添加请求事件
//当客户端有请求来的时候
app.on('request', (req, res) => {
//获取请求地址 req.url
if (req.url == '/index' || req.url == '/') {
res.end('shouye');
} else {
res.end('404 Not');
}
//res.end('<h2>hello user</h2>');
});
//服务器创建好之后 要监听端口
app.listen(3000);
console.log('网站服务器启动成功');
//要先用Node命令执行这个文件
//目前这个地步输出的是 <h2>hello user</h2>
获取请求的方式 req,method: 得到的是大写的GET POST
//创建网站服务器
//需要依赖http模块
const http = require('http');
//进行服务器创建 返回值是网站服务器对象
const app = http.createServer();
//为网站服务器添加请求事件
//当客户端有请求来的时候
app.on('request', (req, res) => {
//req请求对象 res响应对象
//获取请求方式req.method get与post 例如可以通过提交表单发表post请求
//console.log(req.method);
//根据不同的请求方式返回不同的内容
if (req.method == 'POST') {
res.end('post');
} else if (req.method == 'GET') {
res.end('GET');
}
//res.end('<h2>hello user</h2>');
});
//服务器创建好之后 要监听端口
app.listen(3000);
console.log('网站服务器启动成功');
//要先用Node命令执行这个文件
//目前这个地步输出的是 <h2>hello user</h2>
响应报文
设置响应报文的代码:
//创建网站服务器
//需要依赖http模块
const http = require('http');
//进行服务器创建 返回值是网站服务器对象
const app = http.createServer();
//为网站服务器添加请求事件
//当客户端有请求来的时候
app.on('request', (req, res) => {
//书写响应报文 书写 http状态码 响应报文信息
res.writeHead(200, {
'content-type': 'text/html;charset=utf8'
})
});
//服务器创建好之后 要监听端口
app.listen(3000);
console.log('网站服务器启动成功');
//要先用Node命令执行这个文件
//目前这个地步输出的是 <h2>hello user</h2>
上文中writeHead包含两个部分 分别是HTTP状态码和内容类型
HTTP请求与响应处理
请求参数
客户端向服务器端发送请求时,有时需要携带一些客户信息,客户信息需要通过请求参数的形式传递到服务器端,比如登录操作。
GET请求参数
参数被放置在浏览器地址栏中,例如:http://localhost:3000/?name=zhangsan&age=20
参数获取需要借助系统模块url,url模块用来处理url地址
前文说的req.url会把请求参数与请求地址一起输出 不方便分别解析
所以引入url系统模块 用于处理url地址 urll.pase可以把每部分分别解析并返回对象
//创建网站服务器
//需要依赖http模块
const http = require('http');
// 用于处理url地址
const url = require('url');
//进行服务器创建 返回值是网站服务器对象
const app = http.createServer();
//为网站服务器添加请求事件
//当客户端有请求来的时候
app.on('request', (req, res) => {
//书写响应报文 书写 http状态码 响应报文信息
res.writeHead(200, {
'content-type': 'text/html;charset=utf8'
});
console.log(url.parse(req.url, true));
//第一个参数要解析的url地址 第二个参数将查询参数转化为对象形式
let { query, pathname } = url.parse(req.url, true);
//pathname是不包含请求参数的请求地址
//获取请求地址 req.url
if (pathname == '/index' || pathname == '/') {
res.end('<h2>欢迎来到首页</h2>');
} else {
res.end('404 Not');
}
});
//服务器创建好之后 要监听端口
app.listen(3000);
console.log('网站服务器启动成功');
//要先用Node命令执行这个文件
//目前这个地步输出的是 <h2>hello user</h2>
POST请求参数
参数被放置在请求体中进行传输 请求报文中
获取POST参数需要使用data事件和end事件
使用querystring系统模块将参数转换为对象格式
// 用于创建网站服务器的模块
const http = require('http');
// app对象就是网站服务器对象
const app = http.createServer();
// 处理请求参数模块 将HTTP参数转换为对象格式
const querystring = require('querystring');
// 当客户端有请求来的时候
app.on('request', (req, res) => {
// post参数是通过事件的方式接受的
// data 当请求参数传递的时候触发data事件
// end 当参数传递完成的时候触发end事件
//为了减少压力 post请求参数可能不是以此传输完成的
let postParams = '';
req.on('data', params => {
postParams += params;
});
req.on('end', () => { console.log(querystring.parse(postParams));
});
res.end('ok');
});
// 监听端口
app.listen(3000);
console.log('网站服务器启动成功');
路由
路由是指客户端请求地址与服务器端程序代码的对应关系。简单的说,就是请求什么响应什么。
// 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') {
}
});
app.listen(3000);
console.log('服务器启动成功')
静态资源
服务器端不需要处理,可以直接响应给客户端的资源就是静态资源,不论谁访问得到的结果都一样,例如CSS、JavaScript、image文件。
要使用路径拼接 将得到的请求地址最终转换为在硬盘中的地址
const http = require('http');
const url = require('url');
const path = require('path');
const fs = require('fs');
//mime模块可以得到返回的类型
const mime = require('mime');
const app = http.createServer();
app.on('request', (req, res) => {
// 获取用户的请求路径
let pathname = url.parse(req.url).pathname;
//默认输出的也是default.html
pathname = pathname == '/' ? '/default.html' : pathname;
// 将用户的请求路径转换为实际的服务器硬盘路径
let realPath = path.join(__dirname, 'public' + pathname);
//根据地址得到要返回的类型 从而写进响应报文中 这样不用每次手动设置返回类型 返回类型不设置的话对于一些高级浏览器也没有影响
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;
}
res.writeHead(200, {
'content-type': type
})
res.end(result);
});
});
app.listen(3000);
console.log('服务器启动成功')
动态参数
相同的请求地址不同的响应资源,这种资源就是动态资源
客户端请求途径
- GET方式
浏览器地址栏
link标签的href属性
script标签的src属性
img标签的src属性
Form表单提交
2.POST方式
Form表单提交