Node.js开发-HTTP协议

HTTP协议

1) 概念

HTTP(hypertext transport protocol)协议;中文叫超文本传输协议

是一种基于TCP/IP的应用层通信协议

协议中主要规定了两个方面的内容

  • 客户端:用来向服务器发送数据,可以被称之为请求报文

  • 服务端:向客户端返回数据,可以被称之为响应报文

报文:可以简单理解为就是一堆字符串

2) 请求报文的组成

组成:

  • 请求行
  • 请求头
  • 空行
  • 请求体

3) HTTP 的请求行

请求行

4) HTTP 请求头

格式:『头名:头值』

常见的请求头有:

请求头 解释
Host 主机名
Connection 连接的设置 keep-alive(保持连接);close(关闭连接
Cache-Control 缓存控制 max-age = 0 (没有缓存)
Upgrade-Insecure-Requests 将网页中的http请求转化为https请求(很少用)老网站升级
User-Agent 用户代理,客户端字符串标识,服务器可以通过这个标识来识别这个请求来自哪个客户端 ,一般在PC端和手机端的区分
Accept 设置浏览器接收的数据类型
Accept-Encoding 设置接收的压缩方式
Accept-Language 设置接收的语言 q=0.7 为喜好系数,满分为1
Cookie

5) HTTP 的请求体

请求体内容的格式是非常灵活的,

  • (可以是空)==> GET请求,
  • (也可以是字符串,还可以是JSON)===> POST请求

例如:

  • 字符串:keywords=手机&price=2000

  • JSON:{"keywords":"手机","price":2000}

6) 响应报文的组成

1.响应行

复制代码
HTTP/1.1 200 OK

2.响应头

复制代码
Cache-Control:缓存控制 private 私有的,只允许客户端缓存数据
Connection 链接设置
Content-Type:text/html;charset=utf-8 设置响应体的数据类型以及字符集,响应体为html,字符集utf-8
Content-Length:响应体的长度,单位为字节

3.空行

4.响应体

响应体内容的类型是非常灵活的,常见的类型有 HTML、CSS、JS、图片、JSON

7) 创建 HTTP 服务

使用 nodejs 创建 HTTP 服务

js 复制代码
// 1.导入http模块
const http = require("http");

// 2.创建服务对象
const server = http.createServer((request, response) => {
    response.end("Hello Http Server"); // 设置响应体
});

// 3.监听端口,启动服务
server.listen(9000, () => {
    console.log("服务已经启动。。。");
});

http.createServer 里的回调函数的执行时机: 当接收到 HTTP 请求的时候,就会执行

8) 获取 HTTP请求报文

想要获取请求的数据,需要通过 request 对象

含义 语法
请求方法 request.method
请求版本 request.httpVersion
请求路径 request.url
URL 路径 require('url').parse(request.url).pathname
URL 查询字符串 require('url').parse(request.url, true).query
请求头 request.headers
请求体 request.on('data', function(chunk){}); request.on('end', function(){});

注意事项:

  • 1.request.url 只能获取路径以及查询字符串,无法获取 URL 中的域名以及协议的内容
  • 2.request.headers 将请求信息转化成一个对象,并将属性名都转化成了『小写』
  • 3.关于路径:如果访问网站的时候,只填写了 IP 地址或者是域名信息,此时请求的路径为『 / 』
  • 4.关于 favicon.ico:这个请求是属于浏览器自动发送的请求
js 复制代码
//1. 导入 http 模块
const http = require('http');

//2. 创建服务对象
const server = http.createServer((request, response) => {
  //获取请求的方法
  // console.log(request.method);
  //获取请求的 url
  // console.log(request.url);// 只包含 url 中的路径与查询字符串
  //获取 HTTP 协议的版本号
  // console.log(request.httpVersion);
  //获取 HTTP 的请求头
  console.log(request.headers);
  response.end('http'); //设置响应体
});

//3. 监听端口, 启动服务
server.listen(9000, () => {
  console.log('服务已经启动....')
});

9) 设置 HTTP 响应报文

作用 语法
设置响应状态码 response.statusCode
设置响应状态描述 response.statusMessage ( 用的非常少 )
设置响应头信息 response.setHeader('头名', '头值')
设置响应体 response.write('xx'); response.end('xxx');
js 复制代码
//导入 http 模块
const http = require('http');

//创建服务对象
const server = http.createServer((request, response) => {
    // 设置响应码
    response.statusCode = 200;
    // 设置响应状态描述
    response.statusMessage = "I LOVE YOU";
    // 设置响应头
    response.setHeader("content-type", "text/html;charset=utf-8");
    response.end("response");
});

//3. 监听端口, 启动服务
server.listen(9000, () => {
  console.log('服务已经启动....')
});

10) 设置资源类型(mime类型)

媒体类型(通常称为 Multipurpose Internet Mail Extensions 或 MIME 类型 )是一种标准,用来表示文档、文件或字节流的性质和格式

复制代码
mime 类型结构: [type]/[subType]
例如: text/html text/css image/jpeg image/png application/json

HTTP 服务可以设置响应头 Content-Type 来表明响应体的 MIME 类型,浏览器会根据该类型决定如何处理资源

下面是常见文件对应的 mime 类型

js 复制代码
html: 'text/html',
css: 'text/css',
js: 'text/javascript',
png: 'image/png',
jpg: 'image/jpeg',
gif: 'image/gif',
mp4: 'video/mp4',
mp3: 'audio/mpeg',
json: 'application/json'

对于未知的资源类型,可以选择 application/octet-stream 类型,浏览器在遇到该类型的响应时,会对响应体内容进行独立存储,也就是常见的 下载 效果

js 复制代码
/**
 * 创建一个Http服务,端口为9000
 *  GET /index.html         响应 page/index.html
 *  GET /css/app.css        响应 page/css/app.css
 *  GET /images/logo.png    响应 page/image/log.png
 */
const http = require("http");
const fs = require("fs");
const path = require("path");
// 声明变量
let mines = {
    html: 'text/html',
    css: 'text/css',
    js: 'text/javascript',
    png: 'image/png',
    jpg: 'image/jpeg',
    gif: 'image/gif',
    mp4: 'video/mp4',
    mp3: 'audio/mpeg',
    json: 'application/json'
}

const server = http.createServer((request, response) => {
    if (request.method != "GET") {
        response.statusCode = 405;
        response.end("<h1>Method Not Allowed</h1>");
    }
    // 获取url请求路径
    let {pathname} = new URL(request.url, "http:127.0.0.1");
    // 拼接根路径
    let root = __dirname + "/page"
    // 拼接文件路径
    let filePath = root + pathname;
    // 读取文件fs异步api
    fs.readFile(filePath, (err, data) => {
        if (err) {
            response.setHeader("content-type", "charset=utf-8");
            // 判断错误的代号
            switch (err.code) {
                case "ENOENT":
                    response.statusCode = 404;
                    response.end("<h1>Not Found</h1>");
                case 'EPERM':
                    response.statusCode = 403;
                    response.end("<h1>Forbidden</h1>");
                default:
                    response.statusCode = 500;
                    response.end("<h1>Bye Bye</h1>");
            }
            return;
        }
        // 获取文件后缀名
        let ext = path.extname(filePath).slice(1);
        // 获取对应的类型
        let type = mines[ext];
        if (type) {
            // 匹配到了
            if (ext === "html") {
                response.setHeader("content-type", type + ";charset=utf-8");
            } else {
                response.setHeader("content-type", type);
            }
        } else {
            // 没有匹配到
            response.setHeader("content-type", "application/octet-stream");
        }
        
        response.end(data);
    });

});

server.listen(9000, () => {
    console.log("服务启动。。。");
});

11) GET和POST请求的区别

GET 和 POST 是 HTTP 协议请求的两种方式:

  • GET 主要用来获取数据,POST 主要用来提交数据
  • GET 带参数请求是将参数缀到 URL 之后,在地址栏中输入 url 访问网站就是 GET 请求,POST 带参数请求是将参数放到请求体中
  • POST 请求相对 GET 安全一些,因为在浏览器中参数会暴露在地址栏
  • GET 请求大小有限制,一般为 2K,而 POST 请求则没有大小限制
相关推荐
白嫖一茶几秒前
TCP/IP协议中三次握手(Three-way Handshake)与四次挥手(Four-way Wave)
网络·网络协议·tcp/ip
amber66666!43 分钟前
RPC是啥?
网络·网络协议·rpc
byxdaz44 分钟前
QT编程之HTTP服务端与客户端技术
开发语言·qt·http
不想说话的麋鹿2 小时前
「项目实战」从0搭建NestJS后端服务(一):初始化项目+手把手整合Swagger接口文档
node.js·全栈
玩转4G物联网5 小时前
玩转物联网-4G模块如何快速将数据上传到巴法云(TCP篇)
物联网·网络协议·tcp/ip·iot·核心板·fs800dtu·巴法云
阿陈陈陈5 小时前
【Node.js入门笔记8---fs的一些高级功能】
笔记·node.js
MoLingDong6 小时前
PyCharm中pyexecjs调用Node的救赎之路:当Anaconda与fnm狭路相逢
python·node.js
啊糊先森6 小时前
mac切换本地node版本
macos·node.js·mac
新新coder6 小时前
Webpack如何使用抽象语法树来编写插件
前端·javascript·node.js
慢功夫6 小时前
💡如何使用SSE通信(Event-stream)
javascript·网络协议·面试