node入门
来源:SegmentFault
时间:2023-02-24 15:35:36 154浏览 收藏
小伙伴们对数据库编程感兴趣吗?是否正在学习相关知识点?如果是,那么本文《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)
此处注意Document 1111122222然后对相应的路径进行访问:
啦啦啦可以直接访问文件啦!
这是和前端联系很紧密的一节
前端请求后端数据的常用的两种方式:GET和POST。GET的数据是放在url中,POST的数据不在url中。所以对这两种方式,后端需要不同的处理方式。
修改一下上节的1.html:
11111GET
对于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的删除
服务器端使用
Document 我的名字叫:// ciews下ejs.js const ejs = require('ejs') ejs.renderFile("./views/index.ejs", {name: "oneday"}, (err, data) => { if(err) { console.log("编译失败") } else { console.log(data) } })使用
- 不转义的字符串:
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学习网公众号下多多回复交流;文中若有不正之处,也希望回复留言以告知!
-
499 收藏
-
244 收藏
-
235 收藏
-
157 收藏
-
101 收藏
-
176 收藏
-
368 收藏
-
475 收藏
-
266 收藏
-
273 收藏
-
283 收藏
-
- 前端进阶之JavaScript设计模式
- 设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
- 立即学习 542次学习
-
- GO语言核心编程课程
- 本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
- 立即学习 507次学习
-
- 简单聊聊mysql8与网络通信
- 如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
- 立即学习 497次学习
-
- JavaScript正则表达式基础与实战
- 在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
- 立即学习 487次学习
-
- 从零制作响应式网站—Grid布局
- 本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
- 立即学习 484次学习