Hypertext Transfer Protocol (超文本传输协议)
互连网应用最广泛的协议之一
协议:双方必须共同遵从的一组约定
http 协议对浏览器和服务器之间的通信进行约束
请求 => 请求报文
响应 => 响应报文
请求报文结构:
GET [https://www.baidu.com/](https://www.baidu.com/) HTTP/1.1
响应报文
IP 也被称为【IP地址】,本身是一个数字标识(32 Bit 二进制的数字),将其拆分分组转为10进制并用.分割,例如:192.168.1.3
IP用来标识网络设备,用于设备通信
IP为32位的二进制数,即最大为2的32次方,IP不够用
共享IP:共享公网 IP
本机回环IP地址:
局域网 IP (私网 IP):
广域网 IP (公网 IP)
IP 地址分类
应用程序的数字标识
一台现代计算机有 65536 个端口(0 ~ 65535)
一个应用程序可以使用一个或多个端口
作用:实现不同主机应用程序之间的通信
// 1. 引入 http 模块
const http = require('http')
// 2. 创建服务对象
const service = http.createServer((request, response) => {
// request=>请求报文的封装对象
// response=>对响应报文的封装
response.end('hello world') //设置响应体,并结束服务
})
// 3. 监听端口,启动服务
service.listen(9000, () => {
// 服务启动成功后才会执行
console.log('服务启动成功')
})
ctrl + c
停止服务必须重启服务后才能生效
response.setHeader('content-type','text/html;charset=utf-8');
Error: listen EADDRINUSE: address already in use :::9000
5. 关闭当前正在运行监听端口的服务(`使用较多`)
6. 修改其它端口号
如果端口被其它程序占用,可以使用
资源监视器
找到占用端口的程序,然后使用任务管理器关闭对应的程序
浏览器控制台,网络
const http = require('http')
const service = http.createServer((request, response) => {
// 1. 获取请求的方法
// console.log(' request.method :>> ', request.method);
// 2. 获取请求的 url
// console.log('request.url :>> ', request.url); // 只包含 url 中的路径与查询字符串
// 3. 获取 HTTP 协议的版本号
// console.log('request.httpVersion :>> ', request.httpVersion);
// 4. 获取 HTTP 的请求头
// console.log('request.headers :>> ', request.headers);
response.end('你好,世界!') //设置响应体,并结束服务
})
注意事项
//这种方法了解就行,有更好用的办法
const service = http.createServer((request, response) => {
let body = ''
request.on('data', chunk => {
body += chunk
})
request.on('end', () => {
console.log('body :>> ', body);
response.end('htllo http')
})
})
service.listen('9000', () => {
console.log('服务请求中……')
})
const url = require('url');
//方法一,使用 url.parse, 但是该语法已被废弃
const service = http.createServer((request, response) => {
// url.parse 的第二个参数为 true 时,查询字符串 query 将会转换为对象
const res = url.parse(request.url, true)
console.log('pathname :>> ', res.pathname);
console.log('query :>> ', res.query);
console.log('query :>> ', res.query.isTest);
response.end('url')
})
//方法二:使用 new URL()
const service = http.createServer((request, response) => {
const res = new URL(request.url, 'http://127.0.0.1')
const keyword = res.searchParams.get('search')
console.log('res :>> ', res);
console.log('keyword :>> ', keyword);
response.end('url')
})
service.listen('9000', () => {
console.log('服务请求中……')
})
const http = require('http');
const service = http.createServer((request, response) => {
// 1. 设置响应状态码
response.statusCode = 203
// 2. 设置响应状态描述,几乎不用,响应状态码一般和响应状态描述一一对应
// response.statusMessage = 'test'
// 3. 设置响应头, 响应头可以设置多个,也可以使用数组设置同名的响应头
response.setHeader('test', ['a','b','c'])
response.setHeader('test2', 'test-2')
// 4. 设置响应体, 响应体可以设置多个,多个的响应体会自动拼接
// 一般使用 write 设置了响应体后,不会再在 end 中设置响应体
response.write('test')
response.write('test2')
// 每一个请求必须有一个,且只有一个 end
response.end()
})
service.listen('9000', () => {
console.log('服务启动中……')
})
如果在 html 文件中引入外部资源,比如 css 和 js 文件,那在请求的时候,会调用多次接口,分开请求外部资源
所以,需要区分开请求的资源,不然都会返回同样的数据
//方法一:在 createServer 回调函数中区分需要获取的资源
//这种区分方法并不好,如果有大量外部资源就很繁琐,需要优化
//可以通过搭建静态资源服务的形式优化
const http = require('http');
const fs = require('fs');
const path = require('path')
const service = http.createServer((request, response) => {
const { pathname } = new URL(request.url, 'http://127.0.0.1')
if(pathname === '/'){
const filePath = path.resolve(__dirname , 'table/index.html')
const html = fs.readFileSync(filePath)
response.end(html)
}else if(pathname === '/index.css'){
const filePath = path.resolve(__dirname , 'table/index.css')
const css = fs.readFileSync(filePath)
response.end(css)
}
else if(pathname === '/index.js'){
const filePath = path.resolve(__dirname , 'table/index.js')
const js = fs.readFileSync(filePath)
response.end(js)
}
else{
response.end('404 not found')
}
})
service.listen('9000', () => {
console.log('服务启动中……')
})
静态资源是指内容长时间不发生改变的资源
,例如图片,视频,css文件,HTML文件,字体文件等
动态资源是指内容经常更新的资源
,例如百度首页,网易首页,京东搜索列表页面等
//方法二:搭建静态资源服务
const http = require('http');
const fs = require('fs');
const path = require('path')
const service = http.createServer((request, response) => {
const { pathname } = new URL(request.url, 'http://127.0.0.1')
const filePath = path.resolve(__dirname , 'table' + pathname)
fs.readFile(filePath, (err, data) => {
if(err){
response.statusCode = 500;
response.end('404 not found')
return
}
response.end(data)
})
})
service.listen('9000', () => {
console.log('服务启动中……')
})
HTTP 服务在哪个文件夹中寻找静态资源,那个文件夹就是静态资源目录
,也被称之为网站根目录
思考:vscode 中使用 live-servier 访问 HTML 时,它启动的服务网站根目录是谁?是vscode打开的文件夹
包括但不限于如下场景:
媒体类型(通常称之为 Multipurpose Internet Mail Extensions 或 MIME 类型)是一种标准,用来表示文档、文件或字节流的性质和格式。
mime 类型结构:[type] / [subType]
例如:text/html text/css image/jpeg image/png application/json
HTTP 服务可以设置响应头 Content-Type 来表明响应体的 MIME 类型,浏览器会根据该类型来决定如何处理资源
下面是常见文件对应的 mime 类型
html: 'text/html',
css:'text/css',
js: 'text/javascript',
png : 'image/png',
jpg: 'image/jpeg',
gif: 'image/gif',
map4: 'video/mp4',
mp3: 'audio/mpeg',
json: 'application/json',
对于未知的类型,可以选择
application/octet-stream
类型,浏览器在遇到该类型的响应时,会对响应体内容进行对立存储,也就是我们常见的下载
效果
浏览器一般具有嗅探的功能,会自动识别请求的资源类型,但是我们设置响应头 Content-Type 来表明响应体的 MIME 类型会更规范一点
const http = require('http');
const fs = require('fs');
const path = require('path')
const mimes = {
html: 'text/html',
css:'text/css',
js: 'text/javascript',
png : 'image/png',
jpg: 'image/jpeg',
gif: 'image/gif',
map4: 'video/mp4',
mp3: 'audio/mpeg',
json: 'application/json',
}
const service = http.createServer((request, response) => {
const { pathname } = new URL(request.url, 'http://127.0.0.1')
const filePath = path.resolve(__dirname , 'table' + pathname)
fs.readFile(filePath, (err, data) => {
if(err){
response.statusCode = 500;
response.end('404 not found')
return
}
const extname = path.extname(filePath).slice(1)
const type = mimes[extname]
if(type){
response.setHeader('content-type',type)
}else{
response.setHeader('content', 'application/octet-stream')
}
response.end(data)
})
})
service.listen('9000', () => {
console.log('服务启动中……')
})
charset=utf-8
,例如response.setHeader('content-type','text/html;charset=utf-8')
Error 错误
常见的有:
GET 请求情况
POST 请求情况
GET 和 POST 是 HTTP 协议请求的两种方式,主要有如下几个区别
相对
GET 安全一些,因为在浏览器中 GET 请求参数会暴露在地址栏