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 小时前
【论文投稿】探索JavaScript前端开发:开启交互之门的神奇钥匙(一)
javascript
凡人的AI工具箱2 小时前
每天40分玩转Django:问题解答(一)
后端·python·django
爬楼的猪3 小时前
OpenAI的对话和图像API简单体验
javascript·python·aigc
爱上语文3 小时前
Http请求响应——响应
java·开发语言·网络协议·http
在线打码5 小时前
网络攻击行为可视化分析系统【数据分析 + 可视化】
javascript·数据挖掘·数据分析·flask·数据可视化
万岳软件开发小城6 小时前
校园食堂供应链管理的智能化:食堂采购系统源码开发详解
php·软件开发·食堂采购系统源码·供应链管理平台
bboysky457 小时前
golang 的 panic
开发语言·后端·golang
小诸葛的博客7 小时前
Go oom分析(一)——使用pprof线上分析
开发语言·后端·golang
肖老师xy7 小时前
uniapp使用chooseLocation安卓篇
android·javascript·uni-app
SyntaxSage7 小时前
Lua语言的软件开发工具
开发语言·后端·golang