第五章:HTTP 协议

这篇具有很好参考价值的文章主要介绍了第五章:HTTP 协议。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

HTTP 协议

一、概念

HTTP(Hypertext Transport Protocol)协议;中文叫超文本传输协议,是一个基于TCP/IP的应用层通信协议

这个协议详细规定了 浏览器 和万维网 服务器 之间互相通信的规则。

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

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

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

二、请求报文的组成

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

第五章:HTTP 协议,NodeJS,node.js,http

三、HTTP 的请求行

HTTP 的请求行是由 请求方法URLHTTP版本号 组成的。如下所示:

第五章:HTTP 协议,NodeJS,node.js,http

  • 请求方法:

    方法 作用
    GET 主要用于获取数据
    POST 主要用于新增数据
    PUT / PATCH 主要用于更新数据
    DELETE 主要用于删除数据
    HEAD / OPTIONS / CONNECT / TRACE 使用相对较少
  • 请求 URL(统一资源定位器)

    例如:http://www.baidu.com:80/index.html?a=100&b=200#logo

    • http:协议(https、ftp、ssh等)
    • www.baidu.com:域名(也可以是 IP 地址)
    • 80:端口号
    • /index.html:路径
    • a=100&b=200:查询字符串
    • #logo:哈希(锚点链接)
  • HTTP 协议版本号

四、HTTP 的请求头

请求头的格式:『头名:头值』。如下所示:

第五章:HTTP 协议,NodeJS,node.js,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 后面会有单独的

可以通过该网址,去查看请求头的含义:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Headers

五、HTTP 的请求体

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

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

例如:

  • 字符串:keywords=手机&price=2000
  • JSON:{"keywords":"手机", "price":2000}

六、响应报文的组成

  1. 响应行

    HTTP/1.1 200 OK
    
    • HTTP/1.1:HTTP协议版本号

    • 200:响应状态码

      常见的状态码:

      状态码 含义 状态描述
      200 请求成功 OK
      403 禁止请求 Forbidden
      404 找不到资源 Not Found
      500 服务器内部错误 Internal Server Error

      还有一些状态码,参考:https://developer.mozilla.org/zh-CN/docs/Web/HTTP/Status

      状态码的分类:

      状态码 含义
      1xx 信息响应
      2xx 成功响应
      3xx 重定向消息
      4xx 客户端错误响应
      5xx 服务端错误响应
    • OK:响应状态描述

    响应状态码和响应字符串关系是一一对应的。

  2. 响应头

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

  4. 响应体

    响应体的内容格式是非常灵活的,常见的响应体格式有:HTML、CSS、JavaScript、图片、视频、JSON

第五章:HTTP 协议,NodeJS,node.js,http

七、创建 HTTP 服务

使用 node.js 创建 HTTP 服务

7-1.操作步骤

// 1.导入 http 模块
const http = require('http')

// 2.创建服务对象(create:创建;server:服务)
// request 意为请求,是对请求报文的封装对象,通过 request 对象可以获得请求报文的数据
// response 意为响应,是对响应报文的封装对象,通过 response 对象可以设置响应报文    
const server = http.createServer((request, response) => {
    response.end('Hello Http Server')    // 设置响应体并结束这个响应
})

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

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

7-2.测试

浏览器请求对应端口

http://127.0.0.1:9000

第五章:HTTP 协议,NodeJS,node.js,http

7-3.注意事项

  1. 命令行 ctrl + c 停止服务

  2. 当服务启动后,更新代码 必须重启服务才能生效

  3. 响应内容中文乱码的解决办法

    response.setHeader('content-type', 'text/html;charset=utf-8')
    
  4. 端口号被占用

    Error: listen EADDRINUSE: address already in use :::9000
    
    • 关闭当前正在运行监听端口的服务(使用较多
    • 修改其他端口号
  5. HTTP 协议默认端口是80。HTTPS 协议的默认端口是443,HTTP 服务开发常用端口有3000,8080,8090,9000等

如果端口被其他程序占用,可以使用 资源监视器 找到占用端口的程序,然后使用 任务管理器 关闭对应的程序

八、浏览器查看 HTTP 报文

点击步骤:

第五章:HTTP 协议,NodeJS,node.js,http

8-1.查看请求行与请求头

第五章:HTTP 协议,NodeJS,node.js,http

8-2.查看请求体

第五章:HTTP 协议,NodeJS,node.js,http

8-3.查看 URL 查询字符串

第五章:HTTP 协议,NodeJS,node.js,http

8-4.查看响应行与响应头

第五章:HTTP 协议,NodeJS,node.js,http

8-5.查看响应体

第五章:HTTP 协议,NodeJS,node.js,http

九、获取 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’, chunk => {})
request.on(‘end’, () => {})

注意事项:

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

9-1.练习

按照以下要求搭建 HTTP 服务:

请求类型(方法) 请求地址 响应体结果
get /login 登录页面
get /reg 注册页面
// 1.导入 http 模块
const http = require('http')

// 2.创建服务对象
const server = http.createServer((request, response) => {
    // 获取请求的方法
    let {method} = request
    // 获取请求的 url 路径
    let {pathname} = new URL(request.url, 'http://127.0.0.1')
    // 设置响应头信息解决中文乱码问题
    response.setHeader('content-type', 'text/html;charset=utf-8')
    // 判断
    if(method === 'GET' && pathname === '/login') {
        response.end('登录页面')
    }else if(method === 'GET' && pathname === '/reg') {
        response.end('注册页面')
    }else {
        response.end('Not Found')
    }
})

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

十、获取 HTTP 响应报文

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

// 创建服务对象
const server = http.createServer((request, response) => {
    // 1.设置响应状态码
    response.statusCode = 203
    // 新设置的响应状态码会覆盖掉上一次设置的
    response.statusCode = 404
    response.statusCode = 200
    // 2.设置响应状态描述
    response.statusMessage = 'iloveyou'
    // 3.设置响应头
    response.setHeader('content-type', 'text/html;charset=utf-8')
    response.setHeader('Server', 'Node.js')
    response.setHeader('myHeader', 'test test test')
    // 设置多个同名但不同值的响应头
    response.setHeader('test', ['a', 'b', 'c'])
    // 4.响应体的设置(可以有多个 write,但 end 有且只有一个,否则会发送报错 write after end)
    response.write('love')
    response.write('love')
    response.write('love')
    response.write('love')
    response.end('云墨书生')
    response.end('xxx')
})

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

write 和 end 的两种使用情况:

// 1.write 和 end 的结合使用,响应体相对分散
response.write('xxx')
response.write('xxx')
response.write('xxx')
response.end()	// 每一个请求,在处理的时候都必须要执行 end 方法的

// 2.单独使用 end 方法,响应体相对集中
response.end('xxx')

10-1.练习

需求: 搭建 HTTP 服务,响应一个 4 行 3 列的表格,并且要求表格有 隔行换色效果,且 点击 单元格能 高亮显示 并且再次 点击变回原来的颜色

// 导入 http 模块
const http = require('http')

// 创建服务对象
const server = http.createServer((request, response) => {
    response.end(`
        <!DOCTYPE html>
        <html lang="zh-CN">
        <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1.0">
            <title>Document</title>
            <style>
                td {
                    padding: 20px 40px;
                }

                table tr:nth-child(odd) {
                    background: #aef;
                }

                table tr:nth-child(even) {
                    background: #fcb;
                }

                .color {
                    background: #222;
                }

                table, td {
                    border-collapse: collapse;
                }
            </style>
        </head>
        <body>
            <table border="1">
                <tr><td></td><td></td><td></td></tr>
                <tr><td></td><td></td><td></td></tr>
                <tr><td></td><td></td><td></td></tr>
                <tr><td></td><td></td><td></td></tr>
            </table>

            <script>
                // 获取所有的 tb
                let tbs = document.querySelectorAll('td')
                // 遍历
                tbs.forEach(item => {
                    item.onclick = function() {
                        if(this.classList.contains("color")) {
                            this.classList.remove("color")
                        }else {
                            this.classList.add("color")
                        }
                    }
                })
            </script>
        </body>
        </html>
    `)
})

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

10-2.优化:

将 html 代码与 Node.js 代码分开,用 fs 模块中的文件读取方法,读取 html 文件内容,再将读取到的内容放入响应体中

// 导入 http 模块
const http = require('http')
// 导入 fs 模块
const fs = require('fs')

// 创建服务对象
const server = http.createServer((request, response) => {
    // 通过读取文件的方法,读取 table.html 文件
    let html = fs.readFileSync(__dirname + '/table.html')
    response.end(html)  // end 方法的参数可以是字符串,还可以是 Buffer
})

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

这样我们就不必在 js 中去写 html 代码,不仅便于编写代码,还便于进行测试。

10-3.扩展

当将 html 文件中的 css 与 js 分开再重新导入到 html 文件,这时再按照上述写法,将无法实现预期效果

原因: 因为无论响应多少次,最终得到的响应体依旧是 html 文件中的内容,而并非是 css 或 js 文件中的内容。
解决方法: 先获取请求的路径,再根据路径去判断当前的请求是谁的,然后响应对应的响应体即可。
缺点: 一旦 css 文件或 js 文件过多,那么我们就需要不断的进行 if 判断,略显繁琐。

// 导入 http 模块
const http = require('http')
// 导入 fs 模块
const fs = require('fs')

// 创建服务对象
const server = http.createServer((request, response) => {
    // 获取请求的路径
    let {pathname} = new URL(request.url, 'http://127.0.0.1')
    if(pathname === '/') {
        // 读取文件内容
        let html = fs.readFileSync(__dirname + '/table.html')
        response.end(html)
    }else if(pathname === '/index.css') {
        // 读取文件内容
        let css = fs.readFileSync(__dirname + '/index.css')
        response.end(css)
    }else if(pathname === '/index.js') {
        // 读取文件内容
        let js = fs.readFileSync(__dirname + '/index.js')
        response.end(js)
    }else {
        response.statusCode = 404
        response.end('<h1>404 Not Found</h1>')
    }
})

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

十一、网页资源的基本加载过程

第五章:HTTP 协议,NodeJS,node.js,http

网页资源的加载都是循序渐进的,首先获取 HTML 的内容,然后解析 HTML 在发送其他资源的请求,如 CSS、JavaScript、图片等。理解了这个内容对于后续的学习与成长有非常大的帮助

十二、静态资源服务

静态资源是指 内容长时间不发生改变的资源,例如图片、视频、CSS 文件、JS 文件、HTML 文件、字体文件等。

动态资源是指 内容经常更新的资源,例如百度首页、网易首页、京东搜索列表页面等。

12-1.网站根目录或静态资源目录

HTTP 服务在哪个文件夹中寻找静态资源,那个文件夹就是 静态资源目录,也称之为 网站根目录

思考:vscode 中使用 live-server 访问 HTML 时,它启动的服务中网站根目录是谁?

答:网站根目录就是 vscode 所打开的文件夹。

12-2.网页中的 URL

网页中的 URL 主要分为两大类:相对路径与绝对路径

(1)绝对路径

绝对路径可靠性强,而且相对容易理解,在项目中运用较多

形式 特点
http://atguigu.com/web(完整) 直接向目标资源发送请求,容易理解。网站的外链会用到此形式
//atguigu.com/web(省略协议) 与当前页面 URL 的协议拼接形成完整 URL 再发送请求。大型网站用的比较多
/web(省略协议、域名、端口) 与当前页面 URL 的协议、主机名、端口拼接形成完整 URL 再发送请求。中小型网站
(2)相对路径

相对路径在发送请求时,需要与当前页面 URL 路径进行 计算,得到完整 URL 后,再发送请求,学习阶段用的较多。

例如当前网页 url 为 http://127.0.0.1:5500/05-HTTP/page/table.html

形式 最终的 URL
./css/app.css http://127.0.0.1:5500/05-HTTP/page/css/app.css
js/app.js http://127.0.0.1:5500/05-HTTP/page/js/app.js
…/img/logo.png http://127.0.0.1:5500/05-HTTP/img/logo.png
…/…/mp4/show.mp4 http://127.0.0.1:5500/05-HTTP/mp4/show.mp4
(3)网页中使用 URL 的场景小结

包括但不限于如下场景:

  • a 标签 href
  • link 标签 href
  • script 标签 src
  • img 标签 src
  • video audio 标签 src
  • form 中的 action
  • AJAX 请求中的 URL

12-3.设置资源类型(mime 类型)

媒体类型(通常称为 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',
mp4: 'video/mp4',
mp3: 'audio/mpeg',
json: 'application/json'

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

第五章:HTTP 协议,NodeJS,node.js,http

静态资源服务代码实例如下:

/**
 * 创建一个 HTTP 服务,端口为 9000,满足如下需求:
 * GET  /index.html         响应    page/index.html 的文件内容
 * GET  /css/app.css        响应    page/css/app.css 的文件内容
 * GET  /images/logo.png    响应    page/images/logo.png 的文件内容
 */

// 导入 http 模块
const http = require('http')
// 导入 fs 模块
const fs = require('fs')
// 导入 path 模块
const path = require('path')
// 声明一个变量
const mimes = {
    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) => {
    // 获取请求 url 的路径
    let {pathname} = new URL(request.url, 'http://127.0.0.1')
    // 通过 if 来判断请求 url 的路径,来响应不同的静态资源,这种方法是不便捷的
    // 优化:先拼接好文件路径,再去读取该文件
    // 声明一个变量
    let root = __dirname + '/page'
    // 拼接文件路径
    let filePath = root + pathname
    // 读取文件 fs 异步
    fs.readFile(filePath, (err, data) => {
        if(err) {
            response.setHeader('content-type', 'text/html;charset=utf-8')
            response.statusCode = 500
            response.end('读取文件失败')
            return
        }
        // 获取文件的后缀名
        let ext = path.extname(filePath).slice(1)
        // 获取对应的类型
        let type = mimes[ext]
        // 判断
        if(type) {
            // 解决乱码问题:在 mime 类型后加上 ';charset=utf-8'
            response.setHeader('content-type', type + ';charset=utf-8')
        }else {
            response.setHeader('content-type', 'application/octet-stream')
        }
        response.end(data)
    })
})

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

十三、GET 和 POST 请求

13-1.GET 和 POST 请求场景小结

GET 请求的情况:

  • 在地址栏直接输入 url 访问
  • 点击 a 链接
  • link 标签引入 css
  • script 标签引入 js
  • img 标签引入图片
  • form 标签中的 method 为 get(不区分大小写)
  • ajax 中的 get 请求

POST 请求的情况:

  • form 标签中的 method 为 post(不区分大小写)
  • AJAX 的 post 请求

13-2.GET 和 POST 请求的区别

GET 和 POST 是 HTTP 协议请求的两种方式。有以下几种区别:文章来源地址https://www.toymoban.com/news/detail-858185.html

  • GET 主要用来获取数据,POST 主要用来提交数据
  • GET 带参数请求是将参数缀到 URL 之后,在地址栏中输入 url 访问网站的就是 GET 请求;POST 带参数请求是将参数放到请求体中
  • POST 请求相对 GET 安全一些,因为 GET 请求在浏览器中参数会暴露在地址栏上
  • GET 请求大小有限制,一般为 2K,而 POST 请求则没有大小限制

到了这里,关于第五章:HTTP 协议的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Node.js HTTP 模块的内存泄露问题

    很久没有逛社区了,晚上回来看了一下最近的情况,突然看到一个内存泄露问题,作为一个 APM 开发者,自然想分析其中的原因。 下面介绍一下具体的问题。看一下 demo。 Node.js v20.3.1 下执行上面代码(node --expose-gc demo.js)输出如下。 可以看到内存不断在增长。下面来分析这

    2024年02月12日
    浏览(73)
  • Node.js怎么搭建HTTP服务器

    在 Node.js 中搭建一个简单的 HTTP 服务器非常容易。以下是一个基本的示例,演示如何使用 Node.js 创建一个简单的 HTTP 服务器: // 导入 http 模块 const http = require(\\\'http\\\'); // 创建一个 HTTP 服务器 const server = http.createServer((req, res) = { // 设置响应头 res.writeHead(200, {\\\'Content-Type\\\': \\\'text/pl

    2024年02月10日
    浏览(63)
  • Node.js http 模块详解:request 对象

    前文介绍了 http 模块的基本用法,主要就是调用 createServer 和 listen 方法来创建和启动服务。要处理具体的 HTTP 请求,就要在 createServer 方法中写点什么。本文来介绍处理请求的两个核心对象之一的 request 。 HTTP 协议最早设计出来,仅仅为了获取网络上的某个 HTML 文档。随着后

    2024年02月08日
    浏览(58)
  • Node.js 发起HTTP请求的5种方式

    HTTP(百度百科):   超文本传输协议(Hyper Text Transfer Protocol,HTTP)是一个简单的请求-响应协议,它通常运行在TCP之上。它指定了客户端可能发送给服务器什么样的消息以及得到什么样的响应。请求和响应消息的头以ASCII形式给出;         可以直接用这个模块来发起 HTT

    2024年02月21日
    浏览(46)
  • 【Node.js学习 day3——http模块】

    命令行 ctrl + c 停止服务 当服务启动后,更新代码必须 重启服务才能生效 响应内容中文乱码的解决办法 端口号被占用 关闭当前正在运行监听端口的服务(使用较多) 修改其他端口号 HTTP协议默认端口是80。HTTP服务开发常用端口有3000,8080,8090,9000等。 想要获取请求的数据,需

    2024年02月02日
    浏览(54)
  • 【使用Node.js搭建自己的HTTP服务器】

    Node.js 是能够在服务器端运行 JavaScript 的开放源代码、跨平台运行环境。Node.js 由 OpenJS Foundation(原为 Node.js Foundation,已与 JS Foundation 合并)持有和维护,亦为 Linux 基金会的项目。Node.js 采用 Google 开发的 V8 运行代码,使用事件驱动、非阻塞和异步输入输出模型等技术来提高

    2024年02月11日
    浏览(65)
  • Node.js-fs、path、http模块

    Node.js 作为一个JavaScript 的运行环境,仅仅提供了基础的功能和 AP1。然而,基于 ode.s 提供的这些基础能,很多强大的工具和框架如雨后春笋,层出不穷,所以学会了 Nodejs,可以让前端程序员胜任更多的工作和岗位: 基于Express 框架(http://www.expressjs.com.cn/),可以快速构建 Web 应用

    2024年02月04日
    浏览(56)
  • 在 Node.js 中发出 HTTP 请求的 5 种方法

    学习如何在 Node.js 中发出 HTTP 请求可能会让人感到不知所措,因为有数十个可用的库,每个解决方案都声称比上一个更高效。一些库提供跨平台支持,而另一些库则关注捆绑包大小或开发人员体验。 在这篇文章中,我们将探讨在 Node.js 中发出 HTTP 请求的五种最流行的方法,并

    2024年02月04日
    浏览(49)
  • 【佳学基因检测】Node.js中http模块的使用

    先看代码: 该代码片段是使用Node.js的http模块创建一个简单的HTTP服务器。我们可以逐句来解释它的功能: http.createServer(function (req, res) { … }: http是Node.js中的核心模块,用于处理HTTP操作。此处的createServer是http模块中的一个方法,它用于创建一个新的HTTP服务器。 function (req,

    2024年02月05日
    浏览(62)
  • node.js内置模块fs,path,http使用方法

    NodeJs中分为两部分 一是V8引擎为了解析和执行JS代码。 二是内置API,让JS能调用这些API完成一些后端操作。 内置API模块(fs、path、http等) 第三方API模块(express、mysql等) fs模块 fs.readFile()方法,用于读取指定文件中的内容。 fs.writeFile()方法,用于向执行的文件中写入内容 path路径处

    2024年02月12日
    浏览(64)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包