当前位置:首页 > 文章列表 > 数据库 > MySQL > node入门

node入门

来源:SegmentFault 2023-02-24 15:35:36 0浏览 收藏

小伙伴们对数据库编程感兴趣吗?是否正在学习相关知识点?如果是,那么本文《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()
})

此时控制台输出:

可获取请求路径的server

这里的

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()
})

可响应请求路径的server

可响应请求路径的server(返回404)

发现可以响应请求了是不是很棒棒!

但是每次都使用

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
11111



    
22222

然后对相应的路径进行访问:

可响应静态文件请求的server

啦啦啦可以直接访问文件啦!

这是和前端联系很紧密的一节

前端请求后端数据的常用的两种方式:GET和POST。GET的数据是放在url中,POST的数据不在url中。所以对这两种方式,后端需要不同的处理方式。

修改一下上节的1.html:



    
11111
用户:
密码:

一个很丑的get方式的表单

GET

对于GET方式,需要处理的是

// server.js
const server = http.createServer((req, res) => {
    console.log('原地转300圈并listen3000端口')

    res.write(req.url)
    res.end()
})
server.listen(3000)

点提交之后,来观察一下页面的变化:

一个很low的get方式的表单

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; i 
const 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方式的表单

之所以要监听两个事件是因为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启动的简易首页

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)

一个简易的get请求的express

而使用

server.use(express.static('public'))

有了上面一句之后就可以访问

server.get('/', (req, res) => {
    res.send(req.query)
    res.end()
})

就可以像下图一样:

一个打印出了密码的简陋express

所以具备了用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) // 下方可以获取到
})

运行后如图:

自行添加的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:

自己设置的1天后过期的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很明显的将原始的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

删除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)
})

会发现报错了~~

一个报了错的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)

    会发现输出如下:

    一个处理了路径的path包

    所以通过以下代码可以完成一个文件上传的小应用~

    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学习网公众号下多多回复交流;文中若有不正之处,也希望回复留言以告知!

版本声明
本文转载于:SegmentFault 如有侵犯,请联系study_golang@163.com删除
MySQL中常用SQL语句的编写MySQL中常用SQL语句的编写
上一篇
MySQL中常用SQL语句的编写
Neo4j: 迁移MySQL的数据到Neo4j
下一篇
Neo4j: 迁移MySQL的数据到Neo4j
查看更多
最新文章
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    542次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    508次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    497次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    484次学习
查看更多
AI推荐
  • 笔灵AI生成答辩PPT:高效制作学术与职场PPT的利器
    笔灵AI生成答辩PPT
    探索笔灵AI生成答辩PPT的强大功能,快速制作高质量答辩PPT。精准内容提取、多样模板匹配、数据可视化、配套自述稿生成,让您的学术和职场展示更加专业与高效。
    16次使用
  • 知网AIGC检测服务系统:精准识别学术文本中的AI生成内容
    知网AIGC检测服务系统
    知网AIGC检测服务系统,专注于检测学术文本中的疑似AI生成内容。依托知网海量高质量文献资源,结合先进的“知识增强AIGC检测技术”,系统能够从语言模式和语义逻辑两方面精准识别AI生成内容,适用于学术研究、教育和企业领域,确保文本的真实性和原创性。
    24次使用
  • AIGC检测服务:AIbiye助力确保论文原创性
    AIGC检测-Aibiye
    AIbiye官网推出的AIGC检测服务,专注于检测ChatGPT、Gemini、Claude等AIGC工具生成的文本,帮助用户确保论文的原创性和学术规范。支持txt和doc(x)格式,检测范围为论文正文,提供高准确性和便捷的用户体验。
    30次使用
  • 易笔AI论文平台:快速生成高质量学术论文的利器
    易笔AI论文
    易笔AI论文平台提供自动写作、格式校对、查重检测等功能,支持多种学术领域的论文生成。价格优惠,界面友好,操作简便,适用于学术研究者、学生及论文辅导机构。
    42次使用
  • 笔启AI论文写作平台:多类型论文生成与多语言支持
    笔启AI论文写作平台
    笔启AI论文写作平台提供多类型论文生成服务,支持多语言写作,满足学术研究者、学生和职场人士的需求。平台采用AI 4.0版本,确保论文质量和原创性,并提供查重保障和隐私保护。
    35次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议隐私政策
返回登录
  • 重置密码