node.js 解析post请求 方法二

news/2024/9/23 10:20:55/

前提:以前面发的node.js解析post请求方法一为模板,具体见 http://t.csdnimg.cn/ABaIn

此文我们运用第二种方法:使用第三方模块formidable对post请求进行解析。

1》代码难点 ***

在Node.js中使用formidable模块来解析POST请求主要涉及到处理文件上传和多部分表单数据(multipart/form-data)以及验证上传内容的重难点。

难点解决思路:你需要创建一个formidable的实例来处理上传的表单数据。

formidable模块会将这些文件临时存储在服务器的某个位置,你需要处理这些临时文件,可能包括移动它们到最终目标的位置。

一、具体要求:

完成注册、登录、已注册的用户表单展示、文件上传功能(也就是表单填写的用户名、密码、性别这三个信息。以及选择的图片上传功能)

二、解析post请求方法二介绍

解析post请求可以通过第三方模块进行解析,如:formidable、body-parser模块等等。此处我们使用最常用的formidable模块来进行操作

三、资源配置

(1)在终端 npm install formidable -save安装formidable模块

(2)页面配置

https://blog.csdn.net/2301_76669854/article/details/138170325里的页面配置相同。唯一不同的点在于我的注册html页面。因为  enctype="multipart/form-data"涉及到文件上传,所以在方法二:使用formidable模块解析post请求时需要添加。需要保持数据格式一致。

方法二中views文件夹下的regist.html页面如下:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>注册</title><link rel="stylesheet" href="../public/css/main.css">
</head>
<body><h1>注册</h1><img src="../public/images/01.png" alt=""><br><form method="post" action="/doRegist" enctype="multipart/form-data"> <input type="text" name="username" placeholder="用户名"><br><input type="password" name="password" placeholder="密码"><br><input type="radio" name="gender" value="男" checked>男<input type="radio" name="gender" value="女">女<br><input type="file" name="head" multiple><br>  <!-- multiple允许选择多个文件 --><input type="submit" value="注册"><br> </form>
</body>
</html>

(3)在终端 npm install underscore -save安装underscore渲染模板引擎 、npm install querystring安装querystring查询模块

四、代码实现

(1)测试代码serve2.js如下:

const http = require('http');
const fs = require('fs');
const path = require('path');
const url = require('url');
// 导入formidable模块
const formidable = require('formidable');
// 声明一个专门存放所有用户的变量
var users;
// 导入查询参数的模块
const querystring = require('querystring')
// 导入underscore渲染模板
const _ = require('underscore');
//使用underscore渲染模板
function render(data) {// 读取模板内容let temp = fs.readFileSync(path.join(__dirname, 'views/404.html'));// 获取渲染函数let compiled = _.template(temp.toString());// 渲染模板return compiled(data);
}
//创建服务器
const server = http.createServer();
//读取文件。读取user.json存放用户数据的文件
fs.readFile(path.join(__dirname, 'data/users.json'), (err, data) => {if (err) {return;} else {users = JSON.parse(data.toString()); //如果读取正确就将读到的内容转换为一个对象存到users里}
})
//服务器做出请求响应
server.on('request', (req, res) => {let objurl = url.parse(req.url); //将url转为一个对象才能获取到它的pathnamelet pathname = objurl.pathname;// 对pathname做处理// 首先解决静态资源处理  (判断方法:startWith、indexOf、search、includes)// startsWith方法  以什么开头if (pathname.startsWith('/public')) {// 找到当前项目文件夹,再将相对路径转为绝对路径let p = path.join(__dirname, pathname);fs.readFile(p, (err, data) => {if (err) {res.end(render({ msg: '访问的文件不存在' })); //可以使用中文,因为现在是html页面去显示的} else {res.end(data);}})} else if (pathname == '/' || pathname == '/home') {let p = path.join(__dirname, 'views/index.html');fs.readFile(p, (err, data) => {if (err) {res.end(render({ msg: '访问的文件不存在' }));} else {res.end(data);}})} else if (pathname == '/regist') { //建一个文件夹data专门来储存数据 里面建一个users.json的文件let p = path.join(__dirname, 'views/regist.html');fs.readFile(p, (err, data) => {if (err) {res.end(render({ msg: '访问的文件不存在' }));} else {res.end(data);}})} else if (pathname == '/login') {let p = path.join(__dirname, 'views/login.html');fs.readFile(p, (err, data) => {if (err) {res.end(render({ msg: '访问的文件不存在' }));} else {res.end(data);}})} else if (pathname == '/doLogin') {let query = querystring.parse(objurl.query);let username = query.username;let password = query.password;// 声明一个变量代表我的判断结果let result = false;for (let user of users) {if (user.username == username && user.password == password) {result = true;break;}}if (result) {res.end(render({ msg: '登录成功' }));} else {res.end(render({ msg: '用户名或密码错误,登录失败' }));}} else if (pathname == '/doRegist' && req.method.toLowerCase() == 'post') {//一、创建新的IncomingForm实例var form = new formidable.IncomingForm({//uploadDir指定上传文件应储存的目录//keepExtensions设为true 意思是 在保存上传的文件时保留其原始拓展名。// multiples设为true 意思是允许上传多个文件uploadDir: path.join(__dirname, 'public/head/'),keepExtensions: true,multiples: true});// 二、解析请求form.parse(req, (err, fields, files) => { //form.parse(req,callback)方法用于解析传入的请求req中的数据,解析完成后调用回调函数// err 若解析错误则err是包含的错误信息// fields 一个包含所有文本字段的对象。这些字段是由表单中的input标签或其他文本输入元素提交的(也就是我表单填写好上传的数据)// files 一个包含所有上传文件的对象if (err) {console.log(err.message);} else {// 若请求解析成功则创建一个新的user对象。该对象包含从表单字段中获取的 username、password、gender、headlet user = {username: fields.username,password: fields.password,gender: fields.gender,head: files.head[0].newFilename //files.head表示regist.html上传的文件<input type="file" name="head" multiple>中的name名为head的字段。由于files.head是一个数组,所以需要files.head[0]来表示上传的第一个head文件。newFilename是由中间件在处理文件上传保存时的新文件名。可自定义}users.push(user); //将这个 user 对象添加到 users 数组的末尾fs.writeFile(path.join(__dirname, 'data/users.json'), JSON.stringify(users), (err) => {if (err) {res.end(render({ msg: '注册失败' }));} else {// 注册成功// 重定向(服务器端主动发起一个请求)到登录页面res.writeHead(302, { 'Location': '/login' });res.end();}})}});}else if (pathname == '/list') {let p = path.join(__dirname, 'views/users.html');fs.readFile(p, (err, data) => {if (err) {res.end(render({ msg: '访问的文件不存在' }));} else {//获得渲染函数 let compiled = _.template(data.toString());// 调用渲染函数来生成html内容let html = compiled({ users: users }); //我们在模板里取的是users的属性,所以不能简写成users,而是users:usersres.end(html);}})}
});
//启动监听
server.listen(3000, '127.0.0.1', () => {console.log('Server is running at http://127.0.0.1:3000');
})

(2)运行结果如图所示

https://img-blog.csdnimg.cn/direct/e8461160b1c94e0ebc01eb6e6936de2a.png" width="480" />

https://img-blog.csdnimg.cn/direct/c82ec413c21a4921b0a80a4af71be222.png" width="464" />

https://img-blog.csdnimg.cn/direct/3088ffa5fde547d7b604bc8d868ed37c.png" width="432" />

https://img-blog.csdnimg.cn/direct/b9c37b05b96c46ea8cf5c2f319189185.png" width="803" />


http://www.ppmy.cn/news/1446093.html

相关文章

Linux基础——Linux开发工具(上)_vim

前言&#xff1a;在了解完Linux基本指令和Linux权限后&#xff0c;我们有了足够了能力来学习后面的内容&#xff0c;但是在真正进入Linux之前&#xff0c;我们还得要学会使用Linux中的几个开发工具。而我们主要介绍的是以下几个&#xff1a; yum, vim, gcc / g, gdb, make / ma…

Laravel11 路由

基本路由 use Illuminate\Support\Facades\Route;Route::get(/greeting, function () {return Hello World; }); 项目初始自带分组&#xff0c;routes文件夹里有api、auth、console、web四个文件。 api项目是php artisan install:api&#xff0c;routes里没有api.php可以执行…

【LeetCode】---15.最小栈

【LeetCode】---15.最小栈 一、题目解析&#xff1a;二、算法原理&#xff1a;三、代码实现&#xff1a; 一、题目解析&#xff1a; 设计一个支持 push &#xff0c;pop &#xff0c;top 操作&#xff0c;并能在常数时间内检索到最小元素的栈。 实现 MinStack 类: MinStack() 初…

【MySQL】MySQL中的原子更新操作:如何模拟MongoDB的`find_one_and_update`

远方有琴 愀然空灵 声声催天雨 涓涓心事说给自己听 月影憧憧 烟火几重 烛花红 红尘旧梦 梦断都成空 雨打湿了眼眶 年年倚井盼归堂 最怕不觉泪已拆两行 我在人间彷徨 寻不到你的天堂 东瓶西镜放 恨不能遗忘 又是清明雨上 折菊寄到你身旁 把你最爱的歌来轻轻唱 …

Python来计算 1,2,3,4 能组成多少个不相同且不重复的三位数?

我们今天的例子是 有 1&#xff0c;2&#xff0c;3&#xff0c;4 四个数字&#xff0c;它们能组成多省个互不相同且无重复的三位数&#xff1f;都分别是多少&#xff1f; 话不多说&#xff0c;我们先上代码 num 0 # 我们写了三个for循环&#xff0c;表示生成的三位数 for i…

FlaUI

FlaUI是一个基于微软UIAutomation技术&#xff08;简称UIA&#xff09;的.NET库&#xff0c;它主要用于对Windows应用程序&#xff08;如Win32、WinForms、WPF、Store Apps等&#xff09;进行自动化UI测试。FlaUI的前身是TestStack.White&#xff0c;由Roemer开发&#xff0c;旨…

Now in Android 4月份更新速览

Now in Android 4月份更新速览 1. 引言 Android 15 Beta的发布标志着Android生态系统的新一轮更新。这次更新旨在提升用户体验和开发效率&#xff0c;让我们一起来了解其中的重要内容。 2. Android 15 Beta介绍 Android 15 Beta带来了一系列新功能&#xff0c;其中包括默认边…

【表格版】英语学习笔记--发音-元音和辅音

以下所有内容来自“AI豆包”。 元音&#xff08;20个&#xff09; 元音单元音&#xff08;12个&#xff09;双元音&#xff08;8个&#xff09;短长(ʊə)发音类似“乌尔”(ɪ)发音类似“一”但短促(iː)发音类似“一”(eɪ)发音类似“诶”(ə)发音类似“额”但短促(əː)发…