Node.js - HTTP

1. HTTP请求

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

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

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

1.1 请求行

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

javascript 复制代码
GET /index.html HTTP/1.1

常见的请求方法:

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

1.2 请求头

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

javascript 复制代码
键: 值
复制代码
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请求

javascript 复制代码
{
    "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)是服务器发送给客户端的信息的一部分,它包含关于响应的元数据。这些头部字段为客户端提供了服务器、资源和响应内容的额外信息。例如内容类型、服务器信息、缓存控制等,以键值对的形式发送。

javascript 复制代码
Content-Type: text/html
Content-Length: 1234

2.3 响应体(Reponse Body)

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

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

响应示例

简单的HTML响应:

javascript 复制代码
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响应

javascript 复制代码
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服务器只需要几行简单的代码:

javascript 复制代码
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库

javascript 复制代码
const http = require("http");

4.2 创建简单的HTTP服务器

javascript 复制代码
const server = http.createServer((request,response)=>{
    response.end("Hello HTTP server");
});

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

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

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

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

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

javascript 复制代码
response.end("Hello HTTP server");

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

4.3 监听启动服务

javascript 复制代码
//监听窗口,启动服务
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 |

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

javascript 复制代码
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不同的请求方式

javascript 复制代码
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

javascript 复制代码
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,响应结果为:

javascript 复制代码
{
    "message": "Hello",
    "query": {
        "name": "John",
        "age": "30"
    }
}

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

javascript 复制代码
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'); //构造URL
    response.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请求处理常使用监听事件的方式进行处理

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

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

html 复制代码
<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>
javascript 复制代码
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");
})

代码详解:

javascript 复制代码
request.on('data', chunk => {
    body += chunk;
});

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

javascript 复制代码
request.on('end', () => {
    console.log(body);
    response.end('HelloHTTP');
});

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

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

5.3 响应设置

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

· 设置响应状态码

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

· 设置响应描述

javascript 复制代码
//2. 响应状态的描述
response.statusMessage = 'iloveu'

· 设置响应头

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

· 设置响应体

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

示例:返回HTML页面

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>
javascript 复制代码
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')
})
javascript 复制代码
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>')
    }
相关推荐
一枚前端小能手1 天前
📜 `<script>`脚本元素 - 从加载策略到安全性与性能的完整指南
前端·javascript
FreeBuf_1 天前
QNAP紧急修复Pwn2Own 2025比赛中遭利用的7个0Day漏洞
网络·安全·web安全
掘金安东尼1 天前
TypeScript为何在AI时代登顶:Anders Hejlsberg 的十二年演化论
前端·javascript·面试
上海云盾安全满满1 天前
安全服务是什么
网络·安全
已黑化的小白1 天前
Rust 的所有权系统,是一场对“共享即混乱”的编程革命
开发语言·后端·rust
执携1 天前
Vue Router (命名视图)
前端·javascript·vue.js
xixixi777771 天前
内部网关协议——OSPF 协议(开放最短路径优先)(链路状态路由协议)
网络·智能路由器
大锦终1 天前
【Linux】网络层与数据链路层中重点介绍
linux·运维·服务器·网络
含若飞1 天前
Vue 中 `watch` 与 `this.$watch` 使用指南
前端·javascript·vue.js
FreeBuf_1 天前
思科CCX软件曝高危RCE:攻击者可利用Java RMI和CCX Editor获取root权限
java·网络·安全