Node.js - HTTP

1. HTTP请求

HTTP(Hypertext Transfer Protocol,超文本传输协议)是客户端和服务器之间通信的基础协议。HTTP 请求是由客户端(通常是浏览器、手机应用或其他网络工具)发送给服务器的消息,用来请求资源或执行操作。

简单来讲就是向服务器发送请求,服务器返回响应给用户端

HTTP请求由三个主要部分组成:

1.1 请求行

包含请求方法、目标资源路径、协议版本。

GET /index.html HTTP/1.1

 常见的请求方法:

方法作用
GET主要作用于获取数据
POST主要作用于新增数据
PUT/PATCH主要作用于更新数据
DELETE主要作用于删除数据

1.2 请求头

提供额外的信息,比如客户端能力,请求参数等,以键值对的形式呈现

键: 值
GET /path/resource HTTP/1.1
Host: www.example.com
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/117.0.0.0 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Cookie: sessionId=abc123; theme=dark
Referer: https://www.google.com

1.3 请求体

用于发送数据,常见于POST或PUT请求

{"username": "user1","password": "password123"
}

2. HTTP响应

HTTP 响应是服务器对客户端 HTTP 请求的回复。它包含状态信息、响应头和(通常)响应体,用于传递客户端所请求的资源或告知请求处理的结果。

HTTP响应基本结构由以下三个部分组成

2.1 状态行(Status Line)

描述响应的总体状态,包括协议版本、状态码和状态文本。

HTTP-Version Status-Code Reason-Phrase

HTTP-Version: 表示服务器使用的HTTP协议版本。

响应状态码: 三位数字的状态码,表示服务器对请求的处理结果,状态码分为五大类:

· 1xx(信息)

· 2xx(成功)

· 3XX(重定向)

· 4XX(客户端错误)

· 5XX(服务端错误)

常见状态码:

状态码含义
200请求成功
403禁止请求
404找不到资源
500服务器内部错误

2.2 响应头(Response Headers)

HTTP响应头(HTTP Response Headers)是服务器发送给客户端的信息的一部分,它包含关于响应的元数据。这些头部字段为客户端提供了服务器、资源和响应内容的额外信息。例如内容类型、服务器信息、缓存控制等,以键值对的形式发送。

Content-Type: text/html
Content-Length: 1234

2.3 响应体(Reponse Body)

包含实际的响应数据,如 HTML 页面、JSON 数据、文件内容等。

仅在部分响应中有(例如 200 OK)。错误响应(如 404)通常没有响应体。

响应示例

简单的HTML响应:

HTTP/1.1 200 OK
Content-Type: text/html
Content-Length: 88<!DOCTYPE html>
<html>
<head><title>Welcome</title>
</head>
<body><h1>Hello, World!</h1>
</body>
</html>

JSON响应

HTTP/1.1 200 OK
Content-Type: application/json
Content-Length: 57{"status": "success","data": {"id": 1,"name": "Alice"}
}

3. IP与端口

3.1 IP

本身就是一个数字标识,是一个32Bit的二进制数字,每8bit(一个字节)为一组

表示网络中的设备,实现设备之间的通信

IP的分类

本机回环IP地址:用于测试和通信的特殊 IP 地址,始终指向本机。常见为http://127.0.0.1

局域网IP(私网IP):分配给局域网中的设备,用于局域网内部通信。

广域网IP(公网IP):分配给设备的唯一 IP 地址,可在互联网上直接访问。

3.2 端口

应用程序的数字标识,一台现代计算机有65536个端口,一个应用程序可以使用一个或者多个端口

实现不同主机应用程序之间的通信。可以理解为端口就是服务器中的每一个房间,在执行特定的任务。

4. 创建HTTP服务器

在Node.js中,创建HTTP服务器只需要几行简单的代码:

const http = require('http');// 创建服务器
const server = http.createServer((req, res) => {// 处理请求res.statusCode = 200; // HTTP状态码res.setHeader('Content-Type', 'text/plain'); // HTTP头信息res.end('Hello, Node.js HTTP Server!'); // 响应内容
});// 启动服务器
server.listen(3000, '127.0.0.1', () => {console.log('Server running at http://127.0.0.1:3000/');
});

其中http协议的默认端口为80,https的默认端口为443。我们来详细讲解代码的每一步。

4.1 导入http库

const http = require("http");

4.2 创建简单的HTTP服务器 

const server = http.createServer((request,response)=>{response.end("Hello HTTP server");
});

http.createServer是Node.js中用于创建服务器的函数,接收一个回调函数作为参数,该回调函数会在每次收到HTTP请求时被调用。  

· request:表示客户端发送的 HTTP 请求对象。包含请求的所有信息,例如方法(GET/POST)、路径、头部等。

· response:表示服务器返回给客户端的 HTTP 响应对象,控制返回的内容、状态等。

response.setHeader('content-type','text/html;charset=utf-8');
//返回相应内容字符为utf-8

 设置返回内容的头部,包含浏览器的文字解码信息

response.end("Hello HTTP server");

结束响应并向客户端发送数据。

4.3 监听启动服务

//监听窗口,启动服务
server.listen(9000,()=>{console.log("服务启动");
})

server.listen启动服务器并监听端口,这里使用9000端口;

第二个参数是一个回调函数。会在服务器成功启动后执行

4.4 停止服务

在命令行中输入ctrl+c

通过资源管理器找到目标端口对应的应用程序,定位对应PID,在任务管理器中关闭即可

5. HTTP请求处理

想要获取请求的数据,需要通过request对象中的属性进行识别处理

5.1 请求路径区分

如下表格所示,request对象中包含诸多属性,通过解析不同的属性,可以区分请求路径,以此做出相应响应

含义语法
请求方法request.method
请求版本request.httpVersion
请求路径request.url
请求头request.headers

通过实现路径区分,可以对不同请求路径做出相应响应:

const server = http.createServer((req, res) => {if (req.url === '/') {res.end('Welcome to the Homepage!');} else if (req.url === '/about') {res.end('This is the About page.');} else {res.statusCode = 404;res.end('Page Not Found.');}
});server.listen(3000, () => {console.log('Server is running on port 3000');
});

5.2 处理请求方式

HTTP请求可以分为GET请求和POST等,GET请求是请求服务器返回一系列内容;POST请求则是向服务器发送对应内容,服务器再返回相应报文。

通过request.method,可以区分HTTP不同的请求方式

const server = http.createServer((req, res) => {if (req.method === 'GET') {res.end('Received a GET request');} else if (req.method === 'POST') {res.end('Received a POST request');} else {res.end('Unsupported request method');}
});server.listen(3000, () => {console.log('Server is running on port 3000');
});

5.2.1 Get请求

 在 GET 请求中,参数通常通过 URL 查询字符串传递。例如:/search?query=nodejs

const http = require('http');
const url = require('url');// 创建 HTTP 服务器
const server = http.createServer((req, res) => {if (req.method === 'GET') {// 解析查询字符串const queryObject = url.parse(req.url, true).query;res.writeHead(200, { 'Content-Type': 'application/json' });res.end(JSON.stringify({ message: 'Hello', query: queryObject }));}
});// 启动服务器
server.listen(3000, () => {console.log('Server is running on http://127.0.0.1:3000');
});

访问http://127.0.0.1:3000/?name=John&age=30,响应结果为:

{"message": "Hello","query": {"name": "John","age": "30"}
}

示例:根据不同的get请求返回对应内容

const http = require('http');const server = http.createServer((request, response) => {//获取请求的方法let {method} = request; //解构赋值等同于let method = request.method;//获取请求的url路径let {pathname} = new URL(request.url,'http://127.0.0.1'); //构造URLresponse.setHeader('content-type','text/html;charset=utf-8')console.log(method);console.log(pathname);if (method === 'GET' && pathname === '/login'){response.end('登录页面');}else if (method === 'GET' && pathname === '/reg'){response.end('注册页面');}else{response.end('404 NOT FOUND');}
});server.listen(9000, () => {console.log("Start, 9000 is been listened");
});

5.2.2 Post请求

在HTTP模块中,post请求处理常使用监听事件的方式进行处理

request.on('',()=>{})
//request.on('事件名',回调函数);

以下是一个Post传递的例子: 

<html><head><title>Document</title></head><body><form action="http://127.0.0.1:9000" content="IE=edge"><input type="text" name='username'><input type="text" name="password"><input type="submit" value="submit"></form></body>
</html>
const http = require('http');
const server = http.createServer((request,response)=>{//获取请求方法let body = '';request.on('data',chunk=>{body += chunk;})request.on('end',()=>{console.log(body)response.end('HelloHTTP')})
})server.listen(9000,()=>{console.log("Start");
})

代码详解:

request.on('data', chunk => {body += chunk;
});

客户端发送的请求包含数据(例如 POST 请求的请求体),这些数据会以“数据块”(chunk)的形式分批传递给服务器。每次接收到一个数据块时,回调函数会被触发,chunk 是当前接收到的这一块数据。

request.on('end', () => {console.log(body);response.end('HelloHTTP');
});

监听请求的end事件,当客户端发送的数据流完全传输完毕时,触发end事件

传入一个回调函数向客户端返回一个响应内容,并结束响应。

5.3 响应设置 

在HTTP请求发出后,服务器将返回对应的报文传输至客户端,response就是对应内容,在其中可以设置相应属性帮助浏览器与客户端识别相应内容

· 设置响应状态码 

//1. 设置响应状态码
response.statusCode = 203;
response.statusCode = 404;

· 设置响应描述 

//2. 响应状态的描述
response.statusMessage = 'iloveu'

· 设置响应头 

//3. 响应头的设置
response.setHeader('Content-type','text/html;charset=utf-8');
response.setHeader('Server','Node.js');
response.setHeader('test',['a','b','c']); //设置多个同名响应头

· 设置响应体 

//4. 响应体的设置
response.write('Hello');
response.end('end'); //有且只有一个end响应

示例:返回HTML页面

<html><head><style>table{width: 500px;height:500px;background-color: beige;}table td{background-color: aqua;}</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></table><script>let tds = document.querySelectorAll('td');tds.forEach(item=>{item.onclick = function(){this.style.background = '#222';}})</script></body>
</html>
const http = require('http');
const fs = require('fs');const server = http.createServer((request,response)=>{//读取文件内容let html = fs.readFileSync('./example.html');response.end(html);
})server.listen(9000,()=>{console.log('This server is been started')
})

const http = require('http')
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('./example.html')response.end(html);}else if(pathname === '/index.css'){let css = fs.readFileSync('./index.css')response.end(css);}else if (pathname === '/index.js'){let js = fs.readFileSync('./index.js')response.end(js);}else{response.statusCode = 404;response.end('<h1>404 NOT FOUND<h1>')}


 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/1829.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[读书日志]8051软核处理器设计实战(基于FPGA)第七篇:8051软核处理器的测试(verilog+C)

6. 8051软核处理器的验证和使用 为了充分测试8051的性能&#xff0c;我们需要测试每一条指令。在HELLO文件夹中存放了整个测试的C语言工程文件。主函数存放在指令被分为五大类&#xff0c;和上面一样。 打开后是这样的文件结构。HELLO.c是主文件&#xff0c;这是里面的代码&am…

深入浅出 Android AES 加密解密:从理论到实战

深入浅出 Android AES 加密解密&#xff1a;从理论到实战 在现代移动应用中&#xff0c;数据安全是不可忽视的一环。无论是用户隐私保护&#xff0c;还是敏感信息的存储与传输&#xff0c;加密技术都扮演着重要角色。本文将以 AES&#xff08;Advanced Encryption Standard&am…

IDEA编译器集成Maven环境以及项目的创建(2)

选择&#xff1a;“File” ---> "Othoer Setting" --> "Settings for New Projects..." --->搜索“Maven” 新建项目 利用maven命令去编译这个项目 利用maven去打包

Open FPV VTX开源之默认MAVLink设置

Open FPV VTX开源之默认MAVLink设置 1. 源由2. 准备3. 连接4. 安装5. 配置6. 测试6.1 启动wfb-ng服务6.2 启动wfb-ng监测6.3 启动QGroundControl6.4 观察测试结果 7. 总结8. 参考资料9. 补充9.1 telemetry_tx异常9.2 DEBUG串口部分乱码9.3 PixelPilot软件问题 1. 源由 飞控图传…

gesp(C++五级)(4)洛谷:B3872:[GESP202309 五级] 巧夺大奖

gesp(C五级)&#xff08;4&#xff09;洛谷&#xff1a;B3872&#xff1a;[GESP202309 五级] 巧夺大奖 题目描述 小明参加了一个巧夺大奖的游戏节目。主持人宣布了游戏规则&#xff1a; 游戏分为 n n n 个时间段&#xff0c;参加者每个时间段可以选择一个小游戏。 游戏中共有…

像JSONDecodeError: Extra data: line 2 column 1 (char 134)这样的问题怎么解决

问题介绍 今天处理返回的 JSON 的时候&#xff0c;出现了下面这样的问题&#xff1a; 处理这种问题的时候&#xff0c;首先你要看一下当前的字符串格式是啥样的&#xff0c;比如我查看后发现是下面这样的&#xff1a; 会发现这个字符串中间没有逗号&#xff0c;也就是此时的J…

道旅科技借助云消息队列 Kafka 版加速旅游大数据创新发展

作者&#xff1a;寒空、横槊、娜米、公仪 道旅科技&#xff1a;科技驱动&#xff0c;引领全球旅游分销服务 道旅科技 &#xff08;https://www.didatravel.com/home&#xff09; 成立于 2012 年&#xff0c;总部位于中国深圳&#xff0c;是一家以科技驱动的全球酒店资源批发商…

导出文件,能够导出但是文件打不开

背景&#xff1a; 在项目开发中&#xff0c;对于列表的查询&#xff0c;而后会有导出功能&#xff0c;这里导出的是一个excell表格。实现了两种&#xff0c;1.导出的文件&#xff0c;命名是前端传输过去的&#xff1b;2.导出的文件&#xff0c;命名是根据后端返回的文件名获取的…

ISP各模块功能介绍

--------声明&#xff0c;本文为转载整理------- ISP各个模块功能介绍&#xff1a; 各模块前后效果对比&#xff1a; 黑电平补偿&#xff08;BLC&#xff09; 在理想情况下&#xff0c;没有光照射的像素点其响应值应为0。但是&#xff0c;由于杂质、受热等其它原因的影响&…

dockerfile实现lnmp

dockerfile实现lnmp 自定义镜像实现整个架构 (基础镜像centos7) nginx cd /opt mkdir nginx mysql php vim Dockerfile docker network create --subnet172.111.0.0/16 mynetwork #创建自定义网段 docker run -itd --name nginx -p 80:80 --cpu-quota 20000 -m 512m -v /op…

DeepSeek-V3技术报告

摘要 https://arxiv.org/pdf/2412.19437v1 我们介绍DeepSeek-V3&#xff0c;这是一个强大的混合专家&#xff08;MoE&#xff09;语言模型&#xff0c;具有6710亿个总参数&#xff0c;每个token激活37亿个参数。为了实现高效推理和经济实惠的训练&#xff0c;DeepSeek-V3采用了…

【spring mvc】文件上传、下载

文件上传&#xff0c;存储至本地目录中 一、代码1、工具类&#xff08;敏感后缀过滤&#xff09;2、文件上传&#xff0c;存储至本地3、文件下载 二、效果演示1、上传1.1、postMan 请求1.2、上传效果 2、下载2.1、下载效果 一、代码 1、工具类&#xff08;敏感后缀过滤&#x…

CryptoMamba:利用状态空间模型实现精确的比特币价格预测

“CryptoMamba: Leveraging State Space Models for Accurate Bitcoin Price Prediction” 论文地址&#xff1a;https://arxiv.org/pdf/2501.01010 Github地址&#xff1a;https://github.com/MShahabSepehri/CryptoMamba 摘要 预测比特币价格由于市场的高波动性和复杂的非线…

dockerfile2.0

dockerfile实现lnmp nginx centos7 mysql centos7 php centos7 自定义镜像来实现整个架构 cd /opt mkdir nginx mysql php cd nginx 拖入nginx和wordpress vim Dockerfile vim nginx.conf ↓ worker_processes 1; events {worker_connections 1024; } http {include …

C#类型转换

C#是静态类型的语言&#xff0c;变量一旦声明就无法重新声明或者存储其他类型的数据&#xff0c;除非进行类型转换。本章的主要任务就是学习类型转换的知识。类型转换有显式的&#xff0c;也有隐式的。所谓显式&#xff0c;就是我们必须明确地告知编译器&#xff0c;我们要把变…

智能物流升级利器——SAIL-RK3576核心板AI边缘计算网关设计方案(一)

近年来&#xff0c;随着物流行业智能化和自动化水平不断提升&#xff0c;数据的实时处理与智能决策成为推动物流运输、仓储管理和配送优化的重要手段。传统的集中式云平台虽然具备强大计算能力&#xff0c;但高延迟和带宽限制往往制约了物流现场的即时响应。为此&#xff0c;我…

【算法篇】前缀和

&#x1f525;个人主页&#xff1a;Quitecoder &#x1f525;专栏&#xff1a;算法笔记仓 前缀和是一种常用于处理数组区间求和问题的技巧。它可以用来减少重复计算&#xff0c;使得多次查询区间和的时间复杂度从 O(n) 降低到 O(1) 目录 1. 一维模版2. 二维模版3. 除自身以外数…

第R4周:LSTM-火灾温度预测

&#x1f368; 本文为&#x1f517;365天深度学习训练营 中的学习记录博客&#x1f356; 原作者&#xff1a;K同学啊 文章目录 一、代码流程1、导入包&#xff0c;设置GPU2、导入数据3、数据集可视化4、数据集预处理5、设置X&#xff0c;y6、划分数据集7、构建模型8、定义训练函…

机组存储系统

局部性 理论 程序执行&#xff0c;会不均匀访问主存&#xff0c;有些被频繁访问&#xff0c;有些很少被访问 时间局部性 被用到指令&#xff0c;不久可能又被用到 产生原因是大量循环操作 空间局部性 某个数据和指令被使用&#xff0c;附近数据也可能使用 主要原因是顺序存…

Windows图形界面(GUI)-QT-C/C++ - Qt图形绘制详解

公开视频 -> 链接点击跳转公开课程博客首页 -> ​​​链接点击跳转博客主页 目录 Qt绘图基础 QPainter概述 基本工作流程 绘图事件系统 paintEvent事件 重绘机制 文字绘制技术 基本文字绘制 ​编辑 高级文字效果 基本图形绘制 线条绘制 ​编辑 形状绘制 …