Node.js入门教程(二十八):GET/POST请求

一、概述

在很多场景中,我们的服务器都需要跟用户的浏览器打交道,如表单提交。

表单提交到服务器一般都使用 GET/POST 请求。

本章节我们将为大家介绍 Node.js GET/POST 请求的处理方式。

二、获取 GET 请求内容

由于 GET 请求直接被嵌入在路径中,URL 是完整的请求路径,包括了 ? 后面的部分,因此你可以手动解析后面的内容作为 GET 请求的参数。

Node.js 中可以使用 URL 构造函数 解析请求的 URL。

URL 对象是 Node.js 中用于解析和操作 URL 的一种标准工具。它提供了方便的接口来访问和修改 URL 的各个组成部分,如协议、主机名、路径、查询参数等。

示例:解析 GET 请求

复制代码
const http = require('http');
const util = require('util');

http.createServer((req, res) => {
    res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8' });

    // 使用 URL 构造函数解析请求的 URL
    const myUrl = new URL(req.url, `http://${req.headers.host}`);

    // 输出 URL 的各个部分
    res.end(util.inspect({
        href: myUrl.href,
        origin: myUrl.origin,
        protocol: myUrl.protocol,
        host: myUrl.host,
        hostname: myUrl.hostname,
        port: myUrl.port,
        pathname: myUrl.pathname,
        search: myUrl.search,
        searchParams: Object.fromEntries(myUrl.searchParams)
    }));
}).listen(3000);

console.log("Server is running at http://localhost:3000");

在浏览器中访问 http://localhost:3000/user?name=教程&url=www.runoob.com,返回结果中会显示 URL 各个部分的解析结果。

获取 URL 的参数

我们可以使用 searchParams.get() 方法来获取 URL 中的查询参数:

复制代码
const http = require('http');

http.createServer((req, res) => {
    res.writeHead(200, { 'Content-Type': 'text/plain; charset=utf-8' });

    // 使用 URL 构造函数解析请求 URL
    const myUrl = new URL(req.url, `http://${req.headers.host}`);

    // 获取查询参数
    const name = myUrl.searchParams.get("name");
    const siteUrl = myUrl.searchParams.get("url");

    res.write("网站名:" + (name || "未提供"));
    res.write("\n");
    res.write("网站 URL:" + (siteUrl || "未提供"));
    res.end();

}).listen(3000);

console.log("Server is running at http://localhost:3000");

在浏览器中访问 http://localhost:3000/user?name=教程&url=www.chenbyte.com,返回结果:

复制代码
网站名:教程
网站 URL:www.chenbyte.com

URL 对象的属性和方法

属性/方法 描述 示例输出
href 完整的 URL 字符串 "http://example.com:8080/path?foo=bar"
origin URL 的源(协议+主机名+端口) "http://example.com:8080"
protocol URL 的协议部分 "http:"
host 主机名和端口号 "example.com:8080"
hostname 主机名,不包含端口号 "example.com"
port 端口号(如果指定) "8080"
pathname 路径名部分 "/path"
search 查询字符串部分(含 ? "?foo=bar"
searchParams URLSearchParams 对象 { foo: 'bar' }
hash 锚点部分(含 # "#section"

URLSearchParams 方法

方法 描述 示例
get(name) 获取指定名称的参数值 searchParams.get("foo")
append(name, value) 追加新的参数 searchParams.append("key", "val")
set(name, value) 设置参数(存在则更新) searchParams.set("foo", "new")
delete(name) 删除指定参数 searchParams.delete("foo")
has(name) 判断参数是否存在 searchParams.has("foo")
forEach(callback) 遍历键值对 searchParams.forEach((v,k) => console.log(k,v))
toString() 转换为字符串 searchParams.toString()

三、获取 POST 请求内容

在 Node.js 中,处理 POST 请求通常需要通过 http 模块来接收请求体中的数据。POST 请求数据不像 GET 请求那样包含在 URL 中 ,而是作为请求体发送。

接收 POST 数据的方式

在 Node.js 中接收 POST 数据时,需要监听并处理 request 对象的 dataend 事件:

事件 说明
data 当数据块到达服务器时触发,数据块作为回调的参数传递
end 当整个请求体接收完毕时触发,这时可以对完整的 POST 数据进行处理

示例:处理 POST 请求

复制代码
const http = require('http');

// 创建 HTTP 服务器
http.createServer((req, res) => {
    // 检查请求方法是否为 POST
    if (req.method === 'POST') {
        let body = '';

        // 监听 data 事件,逐块接收数据
        req.on('data', (chunk) => {
            body += chunk; // 累加接收到的数据块
        });

        // 监听 end 事件,数据接收完毕
        req.on('end', () => {
            // 输出接收到的 POST 数据
            console.log('Received POST data:', body);

            // 设置响应头和内容
            res.writeHead(200, { 'Content-Type': 'text/plain' });
            res.end('POST data received successfully!');
        });

    } else {
        // 非 POST 请求的处理
        res.writeHead(405, { 'Content-Type': 'text/plain' });
        res.end('Only POST requests are supported.');
    }

}).listen(3000, () => {
    console.log('Server is running at http://localhost:3000');
});

测试 POST 请求

可以使用 curl 命令来测试 POST 请求:

复制代码
curl -X POST -d "name=example&age=25" http://localhost:3000

四、处理 JSON 数据

如果 POST 请求发送的是 JSON 数据 ,可以在 req.on('end') 中将接收的数据解析为对象:

复制代码
req.on('end', () => {
    try {
        const parsedData = JSON.parse(body);
        console.log('Received JSON data:', parsedData);
        res.end('JSON data received successfully!');
    } catch (err) {
        res.statusCode = 400;
        res.end('Invalid JSON');
    }
});

五、使用 querystring 模块解析 POST 数据

querystring 模块用于处理 URL 查询字符串和 POST 请求的数据。

对于 application/x-www-form-urlencoded 编码的 POST 请求数据(如表单提交),querystring 模块可以帮助解析请求体,将它转换成 JavaScript 对象。

基本语法

复制代码
var http = require('http');
var querystring = require('querystring');
var util = require('util');

http.createServer(function(req, res) {
    // 定义了一个 post 变量,用于暂存请求体的信息
    var post = '';

    // 通过 req 的 data 事件监听函数,每当接受到请求体的数据,就累加到 post 变量中
    req.on('data', function(chunk) {
        post += chunk;
    });

    // 在 end 事件触发后,通过 querystring.parse 将 post 解析为真正的 POST 请求格式
    req.on('end', function() {
        post = querystring.parse(post);
        res.end(util.inspect(post));
    });
}).listen(3000);

六、完整实例:表单提交

以下实例表单通过 POST 提交并输出数据:

复制代码
var http = require('http');
var querystring = require('querystring');

var postHTML =
    '<html><head><meta charset="utf-8"><title>菜鸟教程 Node.js 实例</title></head>' +
    '<body>' +
    '<form method="post">' +
    '网站名: <input name="name"><br>' +
    '网站 URL: <input name="url"><br>' +
    '<input type="submit">' +
    '</form>' +
    '</body></html>';

http.createServer(function(req, res) {
    var body = "";
    req.on('data', function(chunk) {
        body += chunk;
    });
    req.on('end', function() {
        // 解析参数
        body = querystring.parse(body);
        // 设置响应头部信息及编码
        res.writeHead(200, { 'Content-Type': 'text/html; charset=utf8' });

        if (body.name && body.url) {
            // 输出提交的数据
            res.write("网站名:" + body.name);
            res.write("<br>");
            res.write("网站 URL:" + body.url);
        } else {
            // 输出表单
            res.write(postHTML);
        }
        res.end();
    });
}).listen(3000);

七、GET 与 POST 请求对比

特性 GET POST
数据位置 URL 中(查询字符串) 请求体中
数据大小限制 有(URL 长度限制)
可见性 数据在 URL 中可见 数据在请求体中,不可见
缓存 可缓存 不可缓存
安全性 较低(数据暴露在 URL) 较高
使用场景 查询、获取数据 提交、修改数据
Node.js 获取方式 解析 req.url 监听 dataend 事件

八、本章小结

知识点 说明
GET 请求 数据在 URL 中,使用 URL 构造函数解析查询参数
POST 请求 数据在请求体中,通过 dataend 事件接收
URL 对象 提供 searchParams 操作查询参数
querystring 模块 解析 application/x-www-form-urlencoded 格式数据
JSON 数据处理 使用 JSON.parse() 解析 JSON 格式的 POST 数据

提示 :在实际开发中,推荐使用 Express 框架来处理路由和请求,它提供了更简洁的 req.queryreq.body 方法来获取 GET 和 POST 参数,避免了手动解析的繁琐工作。

相关推荐
小屁孩你滑稽掉了2 小时前
prisma操作数据库的方法使用教程(简洁版)
数据库·node.js·prisma·fastify
__zRainy__4 小时前
Node系列 · Node基础:https 模块
后端·网络协议·http·https·node.js
__zRainy__12 小时前
Node.js Web 框架选型指南:从 Express 到 Hono 的全景对比
前端·node.js·express·koa·nestjs·egg·fastify
__zRainy__18 小时前
Node系列 · Node基础:net 模块
后端·node.js
嘟嘟07171 天前
从浏览器到 hello world:Docker + nginx 反向代理 + Node 最小服务器一次讲清
docker·容器·node.js
FungLeo1 天前
Node 后端实战 · 老系统数据迁移怎么不出乱子?V1→V2 重构实战与 3 个生产坑
node.js·serverless·数据库迁移·d1 数据库
今日无bug1 天前
Tool Use 工具调用 —— 让LLM缸中大脑突破物理限制的3个阶段
node.js·llm·agent
To_OC2 天前
装完 ESLint 它一声不吭?我还以为代码写得多好
后端·node.js·eslint
FungLeo2 天前
Node 后端实战 · 列表查询到底怎么写?一个通用 DSL 封装,过滤分页排序一次搞定
数据库·node.js·serverless·dsl 封装·通用列表查询