node入门
小伙伴们对数据库编程感兴趣吗?是否正在学习相关知识点?如果是,那么本文《node入门》,就很适合你,本篇文章讲解的知识点主要包括MySQL、Cookie、Node.js、session、express。在之后的文章中也会多多分享相关知识点,希望对大家的知识积累有所帮助!
这即将是一篇很长很长的文章...
从一个简单的服务器开始
// server.js const http = require('http') const server = http.createServer(() => { console.log('原地转300圈并listen3000端口') }) server.listen(3000)
首先在终端运行
const server = http.createServer((req, res) => { // 处理请求和响应 console.log('原地转300圈并listen3000端口') res.write('lalala') res.end() })
此时在终端运行
const server = http.createServer((req, res) => { console.log('原地转300圈并listen3000端口') console.log(req.url) res.write('lalala') res.end() })
此时控制台输出:

这里的
const server = http.createServer((req, res) => { console.log('原地转300圈并listen3000端口') switch(req.url) { case '/1.html': res.write('111') break case '/2.html': res.write('222') break default: res.write('404') break } res.end() })


发现可以响应请求了是不是很棒棒!
但是每次都使用
fs.readFile('文件名', (err, data) => { if (err) { // err的处理 console.log(err) } else { // data的处理 console.log(data.toString()) } })
这里之所以要使用
fs.writeFile('文件名', '内容', (err) => { console.log(err) })
学习了
// server.js const http = require('http') const fs = require('fs') const server = http.createServer((req, res) => { console.log('原地转300圈并listen3000端口') const file_name = '/public' + req.url fs.readFile(file_name, (err, data) => { if (err) { res.write('404') } else { res.write(data) } res.end() }) }) server.listen(3000)
此处注意<!-- 1.html --> <meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title><style> div { width: 100px; height: 100px; background-color: #f3f3f3; border: #ccc 1px solid; } </style><div>11111</div><!-- 2.html,别的内容都不变,只修改body下面的 --> <div>22222</div>然后对相应的路径进行访问:
啦啦啦可以直接访问文件啦!
这是和前端联系很紧密的一节
前端请求后端数据的常用的两种方式:GET和POST。GET的数据是放在url中,POST的数据不在url中。所以对这两种方式,后端需要不同的处理方式。
修改一下上节的1.html:
<!-- 别的内容都不变,只修改body下面的 --> <div>11111</div>GET
对于GET方式,需要处理的是
// server.js const server = http.createServer((req, res) => { console.log('原地转300圈并listen3000端口') res.write(req.url) res.end() }) server.listen(3000)点提交之后,来观察一下页面的变化:
emmmm...虽说这确实太不安全了,但是就先学习一下思路嘛...
对于
const server = http.createServer((req, res) => { console.log('原地转300圈并listen3000端口') var get = {} var url = req.url if (url.indexOf('?') !== -1) { var arr = url.split('?') var arr1 = arr[1].split('&') for (let i = 0; iconst queryString = require('querystring') var query = queryString.parse('user=user&pass=123') console.log(query) // { user: 'user', pass: '123' }所以就可以使用这个模块来将处理方式变得简单点~
// server.js const http = require('http') const queryString = require('querystring') const server = http.createServer((req, res) => { console.log('原地转300圈并listen3000端口') var get = {} var url = req.url if (url.indexOf('?') !== -1) { var arr = url.split('?') get = queryString.parse(arr[1]) res.write(JSON.stringify(get)) } res.end() }) server.listen(3000)但是这里还需要
const urlLib = require('url') var url = urlLib.parse('localhost:4000/?user=user&pass=123') console.log(url) // Url { // protocol: 'localhost:', // slashes: null, // auth: null, // host: '4000', // port: null, // hostname: '4000', // hash: null, // search: '?user=user&pass=123', // query: 'user=user&pass=123', // pathname: '/', // path: '/?user=user&pass=123', // href: 'localhost:4000/?user=user&pass=123' }主要看的就是
const urlLib = require('url') var url = urlLib.parse('localhost:4000/?user=user&pass=123', true) console.log(url.query)//{ user: 'user', pass: '123' }// server.js const http = require('http') const urlLib = require('url') const server = http.createServer((req, res) => { console.log('原地转300圈并listen3000端口') var obj = urlLib.parse(url, true) var get = obj.query var url = obj.pathname res.write(JSON.stringify(get)) res.end() }) server.listen(3000)POST
上面的一路看过来已经get到点了...所以来post一下。
先修改之前的1.html,将get方式改为post即可
因为post的数据是放在HTTP报文主体中的,数据获取就是一个很大的问题,所以首先看一下node怎么接收post数据。
node接收post数据主要是使用
req.on('data', (data) => {}) // 每次接收数据时触发 req.on('end', () => {}) // 接收完毕数据时触发因为post数据可以很大,所以对较大的数据包会进行分块再处理。分块可以避免由于种种错误而产生的大块数据重新传输,会浪费资源。
const server = http.createServer((req, res) => { console.log('原地转300圈并listen3000端口') var post = '' req.on('data', (data) => { post += data }) req.on('end', () => { res.write(JSON.stringify(post)) res.end() }) }) server.listen(3000)可以看到显示的数据是这样的;
之所以要监听两个事件是因为POST数据较大时数据也是分块发送的,所以读者朋友可以试一下增加个
const queryString = require('querystring') //... req.on('end', () => { var POST = queryString.parse(post) res.write(JSON.stringify(POST)) res.end() })一个简单的应用
呐呐...来应用一下噻,比如说制作一个注册登录的界面。目前因为没有应用到数据库,就可以直接使用存储几个账号密码的map来模拟一下~
具体代码可以看reg&login。
接下来是express的部分~
express
使用之前应该先安装
// server.js const express = require('express') const server = express() server.listen(3000)emmmm...这个时候使用
server.use('/', (req, res) => { res.send('这是首页') res.end() })此时就会发现首页上有东西啦!
express中的
const server = express() server.get('/', (req, res) => { res.send('get到了') res.end() }) server.post('/', (req, res) => { res.send('post到了') res.end() }) server.listen(3000)而使用
server.use(express.static('public'))有了上面一句之后就可以访问
server.get('/', (req, res) => { res.send(req.query) res.end() })就可以像下图一样:
所以具备了用express搞注册登录的基础知识,可以来一波实践哦~
express实现注册登录
代码可以见2-reg-login
express处理POST请求
上文学习了express使用
const bodyParser = require('body-parser') server.use(bodyParser.urlencoded()) server.use('/', (req, res) => { res.send(req.body) // 使用了bodyParser之后body属性上才会有值 res.end() })然后打开
server.use(bodyParser.urlencoded({ extended: false, limit: 2 * 1024 * 1024 // 限制2M }))这个时候就会发现上图中的提示没有了。
express的一些操作
链式操作
server.use('/', (req, res, next) => { console.log('a') // next() }) server.use('/', (req, res) => { console.log('b') })如上述代码,当没有next时控制台只打印一个a,但是有了next之后,控制权可以交给下一个
server.use((req, res, next) => { req.on('data', ) }) server.use('/', (req, res, next) => { res.send(req.body) // 下方可以获取到 })运行后如图:
那么就可以模仿
server.use((req, res, next) => { var str = '' req.on('data', (data) => { str += data }) req.on('end', () => { req.body = str next() // 注意这里next的位置 }) }) server.use('/', (req, res, next) => { res.send(req.body) })还用之前那个1.html,结果如下图:
这时候想处理成json的话就可以用之前的querystring的parse。
依然是跟前端联系很紧密的一节
呐呐这次要了解的是cookie和session~
cookie设置和读取
可以在chrome浏览器F12 -> Application -> Cookies看到网页的cookie,可以使用
server.use('/', (req, res) => { res.cookie('user', 'oneday', { maxAge: 24 * 1000 * 3600 // 设置时间 }) res.send() })此时查看浏览器控制台就会发现有了这样一个cookie:
不设置maxAge的话cookie会在浏览器关闭后失效。也可以在
server.use('/', (req, res) => { res.cookie('user', 'oneday', { path: '/one', // 设置路径 }) res.send() })如果使用path属性设置了
const cookieParser = require('cookie-parser') server.use(cookieParser()) server.use('/', (req, res) => { res.cookie('user', 'oneday', { path: '/one', maxAge: 24 * 1000 * 3600 }) res.send(req.cookies) // 使用了cookie-parser中间件后才有的cookies属性 })这时如果访问
server.use(cookieParser()) server.use('/', (req, res) => { req.secret = '愿所有的爱和付出都不会被辜负' // 签名密钥 res.cookie('user', 'oneday', { maxAge: 24 * 1000 * 3600, signed: true }) res.send(req.cookies) })可以看到如下图的输出:
可以看到该签了名的cookie很明显的将原始的cookie包含在了内容中,emmmm内容还是可以看到的。但是一旦cookie被修改了就能看得出来啊,所以签名只是能做到防篡改,不能做到直接加密。
签过名的cookie以
// 告诉cookieParser加密使用的字符串 server.use(cookieParser('愿所有的爱和付出都不会被辜负')) server.use('/', (req, res) => { req.secret = '愿所有的爱和付出都不会被辜负' // 签名密钥 res.cookie('user', 'oneday', { maxAge: 24 * 1000 * 3600, signed: true }) res.send(req.signedCookies) // 就可以将签过名的cookie原样输出 })删除cookie
删除cookie则是使用
const cookieParser = require('cookie-parser') const cookieSession = require('cookie-session') server.use(cookieParser()) server.use(cookieSession()) server.use('/', (req, res) => { res.send(req.session) })会发现报错了~~
呐呐来介绍一下这个keys。它的存在是为了预防session劫持的发生,keys是一个密钥数组,可以用来加密,express会循环使用密钥来加密cookie。
server.use(cookieSession({ keys: ['one', 'day', 'oneday'] // keys加密数组,注意使用方法 })) server.use('/', (req, res) => { if (req.session['count'] == null) { req.session['count'] = 1 } else { req.session['count']++ } console.log(req.session['count']) res.send('OK') })会发现每次控制台的session都会刷出来两个数字,那是因为也访问到了
server.use(cookieSession({ name: 'ses', keys: ['one', 'day', 'oneday'], maxAge: 2 * 3600 * 1000 // 2小时 }))session的删除
服务器端使用
<!-- index.ejs --> <meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title> 我的名字叫:// ciews下ejs.js const ejs = require('ejs') ejs.renderFile("./views/index.ejs", {name: "oneday"}, (err, data) => { if(err) { console.log("编译失败") } else { console.log(data) } })使用
<div></div>
- 不转义的字符串:
server.set('views', './views') server.set('view engine', 'ejs') server.get('/index', (req, res) => { res.render('index.ejs', {name: 'oneday'}) })文件上传
这节主要讲怎么用express实现一个文件上传功能。
将1.html内容进行更改:
const express = require('express') const bodyParser = require('body-parser') const server = express() server.use(bodyParser.urlencoded({extended: false})) server.post('/', (req, res) => { res.send(req.body) }) server.listen(3000)此时运行一下试试会发现只打印出来了图片的名称,意思是只上传了文件名。原因是
const multer = require('multer') var objmulter = multer() const server = express() server.use(objmulter.any()) // 可以是single(指定的名称) server.post('/', (req, res) => { res.send(req.files) })这时再运行就会发现有很多buffers数据出来了...但是只要这样的数据肯定是没有什么用处的啊,毕竟我们要的是上传的文件嘛...那就可以像下面这样对数据进行一下处理:
var objmulter = multer({dest: './www/upload'}) // 只改这一行代码,dest指定目标文件夹这是再运行会发现www/upload下面真的会有一个文件,但是是一个很长名字且没有后缀,也就是没有文件类型的一个文件,接下来我们要做的就是给它加一个文件扩展名,要用到一个叫
const path = require('path') var str = "c:\\www\\aaa\\nbb.png" var obj = path.parse(str) console.log(obj)会发现输出如下:
所以通过以下代码可以完成一个文件上传的小应用~
const multer = require('multer') const pathLib = require('path') const fs = require('fs') var objmulter = multer({dest: './www/upload'}) const server = express() server.use(objmulter.any()) server.post('/', (req, res) => { var newName = req.files[0].path + pathLib.parse(req.files[0].originalname).ext // 重命名临时文件 fs.rename(req.files[0].path, newName, (err) => { // fs.rename if (err) { res.send('上传失败') } else { res.send('上传成功') } }) })选择文件并上传后,会发现在www/upload下是真的有该文件的,而且可以正常打开~
数据库操作
这里用到的数据库是mysql,管理工具是Navicat Premium。在node中需要首先
const mysql = require('mysql') const db = mysql.createConnection({ host: 'localhost', // 目标 user: 'root', // 用户名 port: 3306, // 端口号 password: '123456', // 密码 database: 'user_table' // 数据库名 })数据库操作语法统一格式为:
-- INSERT INTO 表(字段列表) VALUES(值列表) INSERT INTO `user_table` (`username`, `password`) VALUES ('one', '123456')
- 删-
-- DELETE FROM 表名 (WHERE 条件) DELETE FROM `user_table` WHERE `username`='one'
- 改-
-- UPDATE 表名 SET 字段=值, 字段=值, 字段=值...(WHERE 条件) UPDATE `user_table` SET `username`='oneday', `password`='233333' WHERE `username`='one'
- 查-SELECT
-- SELELT (内容) FROM 表名 (WHERE 条件) SELECT * FROM `user_table`一些子句
- where
WHERE `age` >= 18 WHERE `age` >= 18 AND `score` 100 OR `score` > 1000
- order
-- ASC -> 升序 | DESC -> 降序 ORDER BY `age` ASC/DESC -- 按价格升序,随后再按销量降序,多条件排序就用逗号分隔 ORDER BY `price` ASC, `sales` DESC
- group
-- 按班级计数 SELECT `class`, COUNT(class) FROM `student_table` GROUP BY `class` -- 每个班级的平均分 SELECT `class`, AVG(score) FROM `student_table` GROUP BY `class` -- 每个班级的最高分和最低分 SELECT `class`, MAX(score), MIN(score) FROM `student_table` GROUP BY `class`今天关于《node入门》的内容介绍就到此结束,如果有什么疑问或者建议,可以在golang学习网公众号下多多回复交流;文中若有不正之处,也希望回复留言以告知!

- 上一篇
- MySQL中常用SQL语句的编写

- 下一篇
- Neo4j: 迁移MySQL的数据到Neo4j
-
- 害羞的夕阳
- 这篇博文真及时,太详细了,很棒,mark,关注楼主了!希望楼主能多写数据库相关的文章。
- 2023-03-12 18:08:23
-
- 甜美的小甜瓜
- 真优秀,一直没懂这个问题,但其实工作中常常有遇到...不过今天到这,看完之后很有帮助,总算是懂了,感谢作者分享文章内容!
- 2023-02-27 11:05:14
-
- 数据库 · MySQL | 1天前 |
- MySQL设置中文界面,超简单教程来了!
- 332浏览 收藏
-
- 数据库 · MySQL | 1天前 | mysql 索引提示
- MySQL进阶必看!FORCE/USE/IGNOREINDEX用法大揭秘
- 182浏览 收藏
-
- 数据库 · MySQL | 1天前 |
- 手把手教你写MySQL存储过程,小白也能轻松上手
- 163浏览 收藏
-
- 数据库 · MySQL | 1天前 | mysql group by
- MySQL分组查询优化:GROUPBY原理+索引优化超全解析
- 324浏览 收藏
-
- 数据库 · MySQL | 1天前 |
- MySQL设置中文语言,轻松拥有中文界面
- 211浏览 收藏
-
- 数据库 · MySQL | 1天前 |
- MySQL建库语句从入门到精通:创建数据库+设置字符集&排序规则(附实例)
- 176浏览 收藏
-
- 数据库 · MySQL | 1天前 |
- 从零开始学MySQL数据库操作,小白轻松变大神!
- 496浏览 收藏
-
- 数据库 · MySQL | 1天前 |
- MySQL插入日期到时间字段,轻松搞定日期格式
- 484浏览 收藏
-
- 数据库 · MySQL | 1天前 | mysql 数据压缩
- MySQL怎么实现高效压缩存储?表压缩+列式存储详细解读
- 272浏览 收藏
-
- 数据库 · MySQL | 1天前 | mysql JOIN优化
- MySQL优化JOIN操作:七大技巧教你提升关联查询速度
- 106浏览 收藏
-
- 数据库 · MySQL | 1天前 |
- MySQL出现中文乱码?超详细解决方案一次性搞定
- 211浏览 收藏
-
- 数据库 · MySQL | 1天前 |
- MySQL主从复制这样配!搞懂这些参数,replication稳了~
- 131浏览 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 542次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 508次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 497次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 484次学习
-
- 茅茅虫AIGC检测
- 茅茅虫AIGC检测,湖南茅茅虫科技有限公司倾力打造,运用NLP技术精准识别AI生成文本,提供论文、专著等学术文本的AIGC检测服务。支持多种格式,生成可视化报告,保障您的学术诚信和内容质量。
- 14次使用
-
- 赛林匹克平台(Challympics)
- 探索赛林匹克平台Challympics,一个聚焦人工智能、算力算法、量子计算等前沿技术的赛事聚合平台。连接产学研用,助力科技创新与产业升级。
- 48次使用
-
- 笔格AIPPT
- SEO 笔格AIPPT是135编辑器推出的AI智能PPT制作平台,依托DeepSeek大模型,实现智能大纲生成、一键PPT生成、AI文字优化、图像生成等功能。免费试用,提升PPT制作效率,适用于商务演示、教育培训等多种场景。
- 56次使用
-
- 稿定PPT
- 告别PPT制作难题!稿定PPT提供海量模板、AI智能生成、在线协作,助您轻松制作专业演示文稿。职场办公、教育学习、企业服务全覆盖,降本增效,释放创意!
- 51次使用
-
- Suno苏诺中文版
- 探索Suno苏诺中文版,一款颠覆传统音乐创作的AI平台。无需专业技能,轻松创作个性化音乐。智能词曲生成、风格迁移、海量音效,释放您的音乐灵感!
- 56次使用
-
- golang MySQL实现对数据库表存储获取操作示例
- 2022-12-22 499浏览
-
- 搞一个自娱自乐的博客(二) 架构搭建
- 2023-02-16 244浏览
-
- B-Tree、B+Tree以及B-link Tree
- 2023-01-19 235浏览
-
- mysql面试题
- 2023-01-17 157浏览
-
- MySQL数据表简单查询
- 2023-01-10 101浏览