Express + Node +mysql implements a front and back end add, delete, change, check and file upload, complete version
preface
Recently I want to learn node.js, implement a add, delete, change, check and file upload interface.
start
Node installation and mysql installation I am here, will not elaborate, for details, please check the rookie tutorial, there are detailed tutorials. Since we are using Express, we will go to the Express website and find an Express application generator. We will use it to create an application skeleton and install Express-Generator
npm install express-generator -g
Copy the code
Then run the following sentence to create an application skeleton
express --view=pug express-demo
Copy the code
The effect is as follows:
cnpm i
Copy the code
After that, you can run the service
npm start
Copy the code
Go to your browser and open localhost:3000 and you’ll see the following image:
Add and delete
Modifying the directory Structure
Create a few folders in the root directory,
. | - config | - mysql. Js | -- -- modules | -- handle. Js | -- json. Js | -- poolextend. Js | -- SQL. Js | -test| | - index. The CSS -- index. HTML | -- index. Js...Copy the code
Here’s how the code encapsulates the database configuration
/* config/mysql.js */
// MySQL database connection configuration encapsulation
var mysql = {
host: 'localhost'.user: 'root'.password: 'root'.database: 'abc'.port: 3306
};
module.exports = mysql;
Copy the code
Concrete logic encapsulation
/* modules/handle.js */
{} req.params contains the object mapped to the specified route "parameter" attribute, if there is route/user/ : {} req.params contains the object mapped to the specified route "parameter" attribute, if there is route/user/ : {} req.params contains the object mapped to the specified route "parameter" attribute, if there is route/user/ : Name, then the "name" property can be used as req.params.name req.body is usually used to parse the data in POST requests +req.query.id converts the ID to an integer */
/ / into the mysql
var mysql = require('mysql');
// Introduce the mysql connection configuration
var mysqlconfig = require('.. /config/mysql');
// Import the connection pool configuration
var poolextend = require('./poolextend');
// Introduce the SQL module
var sql = require('./sql');
// Import json module
var json = require('./json');
var fs = require('fs');
// Use connection pooling to improve performance
var pool = mysql.createPool(poolextend({}, mysqlconfig));
var userData = {
add: function (req, res, next) {
pool.getConnection(function (err, connection) {
var param = req.query || req.params;
connection.query(sql.insert, [param.id, param.name, param.age, ], function (err, result) {
if (result) {
result = 'add'
}
// Return the result of the operation to the foreground page in json form
json(res, result);
// Release the connection
connection.release();
});
});
},
delete: function (req, res, next) {
pool.getConnection(function (err, connection) {
var id = +req.query.id;
connection.query(sql.delete, id, function (err, result) {
if (result.affectedRows > 0) {
result = 'delete';
} else {
result = undefined;
}
json(res, result);
connection.release();
});
});
},
update: function (req, res, next) {
var param = req.body;
if (param.name == null || param.age == null || param.id == null) {
json(res, undefined);
return;
}
pool.getConnection(function (err, connection) {
connection.query(sql.update, [param.name, param.age, +param.id], function (err, result) {
if (result.affectedRows > 0) {
result = 'update'
} else {
result = undefined;
}
json(res, result);
connection.release();
});
});
},
queryById: function (req, res, next) {
var id = +req.query.id;
pool.getConnection(function (err, connection) {
connection.query(sql.queryById, id, function (err, result) {
if(result ! =' ') {
var _result = result;
result = {
result: 'select'.data: _result
}
} else {
result = undefined;
}
json(res, result);
connection.release();
});
});
},
queryByName: function (req, res, next) {
var name = req.query.name;
pool.getConnection(function (err, connection) {
connection.query(sql.queryByName, name, function (err, result) {
if(result ! =' ') {
var _result = result;
result = {
result: 'select'.data: _result
}
} else {
result = undefined;
}
json(res, result);
connection.release();
});
});
},
queryAll: function (req, res, next) {
pool.getConnection(function (err, connection) {
connection.query(sql.queryAll, function (err, result) {
if(result ! =' ') {
var _result = result;
result = {
result: 'selectall'.data: _result
}
} else {
result = undefined; } json(res, result); connection.release(); }); }); }};module.exports = userData;
Copy the code
Response data encapsulation
//json.js
// Encapsulate the pickup module
var json = function(res, result) {
if (typeof result === 'undefined') {
res.json({
code: '1'.msg: 'Operation failed'
});
} else if (result === 'add') {
res.json({
code: '200'.msg: 'Added successfully'
});
} else if (result === 'delete') {
res.json({
code: '200'.msg: 'Deleted successfully'
});
} else if (result === 'update') {
res.json({
code: '200'.msg: 'Changed successfully'
});
} else if(result.result ! ='undefined' && result.result === 'select') {
res.json({
code: '200'.msg: 'Search successful'.data: result.data
});
} else if(result.result ! ='undefined' && result.result === 'selectall') {
res.json({
code: '200'.msg: 'All found successful'.data: result.data
});
} else{ res.json(result); }};module.exports = json;
Copy the code
Connection pool encapsulation
//poolextent.js
// Connection pool extension encapsulation
var poolextend = function(target, source, flag) {
for (var key in source) {
if (source.hasOwnProperty(key)) {
flag ? (target[key] = source[key]) : (target[key] === void 0&& (target[key] = source[key])); }}return target;
}
module.exports = poolextend;
Copy the code
SQL statement encapsulation
//sql.js
// SQL statement encapsulation
var user = {
insert:'INSERT INTO userlist(id, name, age) VALUES(? ,? ,? ,? ,?) '.update:'UPDATE userlist SET name=? , age=? WHERE id=? '.delete: 'DELETE FROM userlist WHERE id=? '.queryById: 'SELECT * FROM userlist WHERE id=? '.queryByName: `SELECT * FROM userlist WHERE name LIKE CONCAT('%',? , '%') `.queryAll: 'SELECT * FROM userlist'};module.exports = user;
Copy the code
And then the routing file we’re going to modify
//router/index.js
var express = require('express');
var router = express.Router();
var user = require('.. /modules/handle');
/* GET users listing. */
router.get('/'.function(req, res, next) {
res.render('index', { title: 'SQL for MySQL' });
});
router.get('/addUser'.function(req, res, next) {
user.add(req, res, next);
});
router.get('/queryAll'.function(req, res, next) {
user.queryAll(req, res, next);
});
router.get('/query'.function(req, res, next) {
user.queryById(req, res, next);
});
router.get('/queryName'.function(req, res, next) {
user.queryByName(req, res, next);
});
router.get('/deleteUser'.function(req, res, next) {
user.delete(req, res, next);
});
router.get('/update'.function(req, res, next) {
res.render('update');
});
router.post('/updateUser'.function(req, res, next) {
user.update(req, res, next);
});
module.exports = router;
Copy the code
App file let’s set it up to allow cross-domain
var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users');
var app = express();
// Set to allow cross-domain access to the service.
app.all(The '*'.function (req, res, next) {
res.header('Access-Control-Allow-Origin'.The '*');
// Access-control-allow-headers, which can be viewed according to F12 of browser, paste the corresponding Headers here
res.header('Access-Control-Allow-Headers'.'Content-Type');
res.header('Access-Control-Allow-Methods'.The '*');
res.header('Content-Type'.'application/json; charset=utf-8');
next();
});
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine'.'jade');
app.use(logger('dev'));
app.use(express.json());
app.use(express.urlencoded({
extended: false
}));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));
app.use('/', indexRouter);
app.use('/users', usersRouter);
// catch 404 and forward to error handler
app.use(function (req, res, next) {
next(createError(404));
});
// error handler
app.use(function (err, req, res, next) {
// set locals, only providing error in development
res.locals.message = err.message;
res.locals.error = req.app.get('env') = = ='development' ? err : {};
// render the error page
res.status(err.status || 500);
res.render('error');
});
module.exports = app;
Copy the code
Next you need to install a few dependencies
cnpm i mysql -S
cnpm i multer -S
Copy the code
This is the end of the add, delete, change and check, the next is the front-end code
<! -- test/index.html -->
<html lang="en">
<head>
<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>
<link rel="stylesheet" type="text/css" href="./index.css" />
</head>
<body>
<div class="handler">
<input type="text" id="searchValue" placeholder="Please enter your name for enquiry">
<button id="searchBtn">The query</button>
<button id="resetBtn">reset</button>
<button id="addBtn" class="primary">new</button>
</div>
<div class="table-box">
<table border="0" cellspacing="0" cellpadding="0" id="box">
</table>
</div>
<! -- Add pop-ups -->
<div id="modal">
<div class="dialog-box">
<div class="dialog-box__main">
<div class="main-item">
<label for="">The name</label>
<input type="text" placeholder="Please enter your name" id="nameValue">
</div>
<div class="main-item">
<label for="" >age</label>
<input type="text" placeholder="Please enter a number" id="ageValue">
</div>
</div>
<div class="dialog-box__footer">
<button id="cancelBtn">cancel</button>
<button id="confirmBtn" class="primary">determine</button>
</div>
</div>
</div>
<! -->
<div id="tips">
</div>
<! -- Confirm the box -->
<div id="confirmModal">
<div class="confirm-box">
<h3 class="title">prompt</h3>
<div id="confirmMsg">Are you sure?</div>
<div class="dialog-box__footer">
<button id="confirmCancel">cancel</button>
<button id="confirmOK" class="primary">determine</button>
</div>
</div>
</div>
</body>
</html>
<script src="./index.js"> </script>
Copy the code
/* test/index.css */* {padding: 0;
margin: 0;
}
html.body {
padding: 0;
margin: 0;
width: 100%;
height: 100%;
overflow: hidden;
}
/* Add a new frame */
#modal {
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 8).position: fixed;
top: 0px;
left: 0px;
display: none;
transition:all 1s;
z-index: 99;
}
.dialog-box {
min-width: 300px;
/* height: 200px; * /
background: #ffffff;
border-radius: 3px;
padding: 10px 10px 80px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(50%, 50%);transition:all 1s;
}
#fileBtn{
display:none;
}
#fileAdd{
width:50px;
height:50px;
border:2px solid #ccc;
position: relative;
cursor: pointer;
transition:all .5s;
}
#fileAdd:hover{
box-shadow: 0px 0px 0px 50px #eee inset;
color:#fff;
}
#fileAdd::before{
content:' ';
display: inline-block;
width:20px;
height: 2px;
background:#ccc;
position: absolute;
top:50%;
left:50%;
transform: translate(50%, 50%); }#fileAdd::after{
content:' ';
display: inline-block;
width:2px;
height: 20px;
background:#ccc;
position: absolute;
top:50%;
left:50%;
transform: translate(50%, 50%); }.dialog-box__main{
margin-top: 30px;
}
.dialog-box__footer {
position: absolute;
bottom: 10px;
right: 10px;
}
.dialog-box__footer button {
cursor: pointer;
}
/* Add a pop-up style end */
button {
border: none;
background: #fff;
border-radius: 3px;
padding: 10px 20px;
border: 1px solid #ccc;
margin: 5px;
cursor: pointer;
}
button:hover{
opacity: 0.8;
}
.primary {
background: # 333;
color: #fff;
}
.danger{
background: #ff6666;
color: #fff;
}
.main-item {
display: flex;
align-items: center;
justify-content: start;
margin-bottom: 10px;
}
.main-item label{
margin-right:10px;
width:100px;
}
input {
border-radius: 3px;
padding: 10px 10px;
border: 1px solid #ccc;
}
#tips {
position: fixed;
top: 88px;
left: 50%;
transform: translateX(50%);width: auto;
padding: 5px 20px;
border-radius: 10px;
color: #fff;
transition: all 1s;
display: none;
z-index: 999;
}
.table-box {
overflow-y: scroll;
max-width: 700px;
height: 600px;
overflow: auto;
text-align: center;
margin:10px auto;
position: relative;
}
.table-header{
position: -webkit-sticky;
position: sticky;
top:0px;
color:#fff;
background:# 333;
}
.table-box table {
width:100%;
}
.handler {
padding:10px;
text-align: center;
background:# 333;
}
/* Custom table */
#tableList{
border-bottom:none;
min-width: 600px;
display:flex;
flex-direction: column;
border-right:1px solid #ccc;
box-sizing:border-box;
}
.list-item{
border-bottom:1px solid #ccc;
display:flex;
justify-content: space-around;
align-items:center;
height: 50px;
line-height: 50px;
}
.list-item span{
width:100%;
flex:1;
display:block;
height: 100%;
border-left:1px solid #ccc;
overflow: hidden;
/* Sets the size of the text box */
white-space: nowrap;
/* Sets the content to non-newline */
text-overflow: ellipsis;
/* Set text outside the text box to display as... * /
}
.list-item .list-handler{
flex:2;
}
.empty-text{
line-height: 40px;
border-left:1px solid #ccc;
border-bottom:1px solid #ccc;
}
#box{
border: 1px solid #ccc;
border-bottom:none;
min-width: 600px;
}
#box tr th.#box tr td{
border-bottom:1px solid #ccc;
border-right:1px solid #ccc;
padding:5px 10px;
}
#box tr th{
background:# 333;
color:#fff;
}
#box tr th:last-child.#box tr td:last-child{
border-right:none;
}
/* Confirm the popbox */
#confirmModal{
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 8).position: fixed;
top: 0px;
left: 0px;
display: none;
transition:all 1s;
}
.confirm-box {
width: 300px;
height: 200px;
background: #ffffff;
border-radius: 3px;
padding: 10px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(50%, 50%);transition:all 1s;
}
#confirmMsg{
font-size:16px;
text-align:center;
margin-top:40px;
}
.title{
font-size:18px;
text-align:center;
}
Copy the code
/* test/index.js */
function queryDom(name){
return document.querySelector(name)
}
let dialogBox = queryDom('.dialog-box')
let confirmModal = queryDom('#confirmModal')
let confirmMsg = queryDom('#confirmMsg')
let confirmCancel = queryDom('#confirmCancel')
let confirmOK = queryDom('#confirmOK')
let searchBtn = queryDom('#searchBtn')
let resetBtn = queryDom('#resetBtn')
let searchValue = queryDom('#searchValue')
let box = queryDom('#box')
let nameValue = queryDom('#nameValue')
let ageValue = queryDom('#ageValue')
let addBtn = queryDom('#addBtn')
let confirmBtn = queryDom('#confirmBtn')
let cancelBtn = queryDom('#cancelBtn')
let modal = queryDom('#modal')
let tipsBox = queryDom('#tips')
let delBtn = queryDom('.addBtn')
// Specify a variable that controls whether to add or edit
let flag = 'add'
let gobj = {} // Temporarily store edit data
// Query the list once when the page loads
window.onload = function () {
getList()
}
/ * -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- click event parts -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - * /
searchBtn.onclick = function () {
getListByName(searchValue.value)
}
/ / reset
resetBtn.onclick = function () {
searchValue.value = ' '
getList()
}
// Edit and delete
box.onclick = function (e) {
if (e.target.className.indexOf('updateBtn') >- 1) {
modal.style.display = 'block'
modal.style.opacity = 1
dialogBox.style.left = '50%'
flag = 'edit'
let obj = JSON.parse(e.target.getAttribute('data-item'))
gobj = obj
detail(obj)
} else if (e.target.className.indexOf('delBtn') >- 1) {
let id = e.target.getAttribute('data-id')
confirmBox('This deletes the row. Are you sure? ').then(function(){
del(id)
}).catch(function(){
console.log('Cancel delete')}}}function detail(item) {
nameValue.value = item.name
ageValue.value = item.age
}
/ / new
addBtn.onclick = function () {
modal.style.display = 'block'
modal.style.opacity = 1
dialogBox.style.left = '50%'
flag = 'add'
nameValue.value = ' '
ageValue.value = ' '
}
/ / cancel
cancelBtn.onclick = function () {
setTimeout(function() {
modal.style.display = 'none'
}, 1000);
modal.style.opacity = 0
dialogBox.style.left = '-300px'
}
/ / sure
confirmBtn.onclick = function () {
// Check cannot be null
if(! ageValue.value||! nameValue.value ){ tips.error('Cannot be empty')
return
}
// Check whether the age is a number
if(!/^\d*$/g.test(ageValue.value)){
tips.error('Age please enter a number')
return
}
setTimeout(function() {
modal.style.display = 'none'
}, 1000);
modal.style.opacity = 0
dialogBox.style.left = '-300px'
if (flag === 'add') {
add()
} else if (flag === 'edit') {
update(gobj.id)
}
}
/ * -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- click event parts -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - * /
/ * -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- request part -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - * /
// Delete data
function del(id) {
_ajax({
url: 'http://localhost:3000/deleteUser'.data: {
id: id,
},
success: function (res) {
if (res.code === '200') {
tips.success(res.msg)
getList()
} else {
tips.error(res.msg)
}
},
error: function (e) {
console.log(e, 'error')}}}// Get all data
function getList() {
_ajax({
url: 'http://localhost:3000/queryAll'.success: function (res) {
let resData = res.data || []
if (resData) {
renderTable(resData)
}
},
error: function (e) {
console.log(e, 'error')}}}// Query data by name
function getListByName(name) {
_ajax({
url: 'http://localhost:3000/queryName'.data: {
name: name
},
success: function (res) {
let resData = res.data || []
if (resData) {
renderTable(resData)
}
},
error: function (e) {
console.log(e, 'error')}}}// Add data
function add() {
_ajax({
url: 'http://localhost:3000/addUser'.data: {
name: nameValue.value,
age: ageValue.value,
},
success: function (res) {
if (res.code === '200') {
tips.success(res.msg)
getList()
} else {
tips.error(res.msg)
}
},
error: function (e) {
console.log(e, 'error')}}}// Update data
function update(id) {
_ajax({
url: 'http://localhost:3000/updateUser'.method: 'POST'.data: {
id: id,
name: nameValue.value,
age: ageValue.value,
},
success: function (res) {
if (res.code === '200') {
tips.success(res.msg)
getList()
} else {
tips.error(res.msg)
}
},
error: function (e) {
console.log(e, 'error')}}}/ * -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - requested part -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - * /
// Encapsulate render table functions
function renderTable(list){
// Empty the previous table
box.innerHTML = ' '
// Add a header
let headerTrNode = document.createElement('tr')
headerTrNode.innerHTML = X. ` < th > < / th > < th > id < / th > < th > name < / th > < th > age < / th > < th > < / th > operation `
box.appendChild(headerTrNode)
// Render table body according to data
list.forEach((item,index) = >{
let trNode = document.createElement('tr')
trNode.innerHTML = `
<td>${index+1}</td>
<td>${item.id}</td>
<td>${item.name}</td>
<td>${item.age}</td>
<td >
<button class="updateBtn primary" data-item='The ${JSON.stringify(item)}'> edit < / button > & have spent <button class="delBtn danger" data-id="${item.id}</button> </td>
box.appendChild(trNode)
})
}
// Encapsulate the request function
function _ajax(option) {
let url = option.url || ' '
let method = option.method ? option.method.toUpperCase() : 'GET'
let data = option.data || null
// Change the request parameters to form format
var formData = []
for (var key in data) {
formData.push(' '.concat(key, '=', data[key]))
}
data = formData.join('&')
if (method === 'GET') {
url += location.search.length === 0 ? ' '.concat('? ', data) : ' '.concat('&', data)
}
let xhr = new XMLHttpRequest()
xhr.open(method, url, true)
// Set the response parameters to the format passed in or the default JSON format
xhr.responseType = option.responseType || 'json'
xhr.onreadystatechange = (a)= > {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
option.success(xhr.response)
} else {
option.error()
}
}
}
if (method === 'POST') {
// Set the request format for sending data to form format
// xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
// Set the request format for sending data to JSON format
xhr.setRequestHeader('content-type'.'application/json');
}
xhr.send(method === 'POST' ? JSON.stringify(option.data) : null)}/* ---------------- tool function part -------------- */
// Encapsulate a hint function
function Tips() {
var loop
this.error = function (str, delay) {
if(loop){
clearTimeout(loop)
}
tipsBox.style.display = 'block'
tipsBox.style.background = '#ff6666'
tipsBox.innerHTML = str
loop = setTimeout((a)= > {
tipsBox.style.display = 'none'
}, delay || 3000)}this.success = function (str, delay) {
if(loop){
clearTimeout(loop)
}
tipsBox.style.display = 'block'
tipsBox.style.background = '#78d626'
tipsBox.innerHTML = str
loop = setTimeout((a)= > {
tipsBox.style.display = 'none'
}, delay || 3000)}}let tips = new Tips()
// Encapsulate a secondary confirmation frame
function confirmBox(msg){
msg = msg || 'Sure to delete? '
confirmMsg.innerHTML = msg
confirmModal.style.display = 'block'
return new Promise(function (resolve,reject) {
confirmOK.onclick = function(){
confirmModal.style.display = 'none'
resolve()
}
confirmCancel.onclick = function(){
confirmModal.style.display = 'none'
reject()
}
});
}
/* ---------------- tool function part -------------- */
Copy the code
After that, let’s create a table for the database, UserList and UploadFiles, which I created along with file upload. It doesn’t make any difference.
Then go back to the project and restart the service
npm start
Copy the code
Add, delete, modify, and check the directory structure.
File upload
It’s all in the code. Let’s go straight to the code. In order to paste and copy, I’m going to go straight to the whole code, so I don’t have to mess it up. It’s too much work. Add a SQL statement to sql.js and modify the statement
//sql.js
// SQL statement encapsulation
var user = {
insert:'INSERT INTO userlist(id, name, age,fileId,fileUrl) VALUES(? ,? ,? ,? ,?) '.update:'UPDATE userlist SET name=? , age=? ,fileId=? ,fileUrl=? WHERE id=? '.delete: 'DELETE FROM userlist WHERE id=? '.queryById: 'SELECT * FROM userlist WHERE id=? '.queryByName: `SELECT * FROM userlist WHERE name LIKE CONCAT('%',? , '%') `.queryAll: 'SELECT * FROM userlist'.upload:'INSERT INTO uploadfiles(fieldname, originalName, tmpName, encoding, mimetype, size, path, tmpPath, addTime) VALUES(? ,? ,? ,? ,? ,? ,? ,? ,?) '
};
module.exports = user;
Copy the code
Then add the upload logic to handle.js and modify the interface
{} req.params contains the object mapped to the specified route "parameter" attribute, if there is route/user/ : {} req.params contains the object mapped to the specified route "parameter" attribute, if there is route/user/ : {} req.params contains the object mapped to the specified route "parameter" attribute, if there is route/user/ : Name, then the "name" property can be used as req.params.name req.body is usually used to parse the data in POST requests +req.query.id converts the ID to an integer */
/ / into the mysql
var mysql = require('mysql');
// Introduce the mysql connection configuration
var mysqlconfig = require('.. /config/mysql');
// Import the connection pool configuration
var poolextend = require('./poolextend');
// Introduce the SQL module
var sql = require('./sql');
// Import json module
var json = require('./json');
var fs = require('fs');
var globalObj = require('.. /config')
// Use connection pooling to improve performance
var pool = mysql.createPool(poolextend({}, mysqlconfig));
var userData = {
add: function (req, res, next) {
pool.getConnection(function (err, connection) {
var param = req.query || req.params;
connection.query(sql.insert, [param.id, param.name, param.age,param.fileId,param.fileUrl], function (err, result) {
if (result) {
result = 'add'
}
// Return the result of the operation to the foreground page in json form
json(res, result);
// Release the connection
connection.release();
});
});
},
delete: function (req, res, next) {
pool.getConnection(function (err, connection) {
var id = +req.query.id;
connection.query(sql.delete, id, function (err, result) {
if (result.affectedRows > 0) {
result = 'delete';
} else {
result = undefined;
}
json(res, result);
connection.release();
});
});
},
update: function (req, res, next) {
var param = req.body;
if (param.name == null || param.age == null || param.id == null) {
json(res, undefined);
return;
}
pool.getConnection(function (err, connection) {
connection.query(sql.update, [param.name, param.age,param.fileId,param.fileUrl, +param.id], function (err, result) {
if (result.affectedRows > 0) {
result = 'update'
} else {
result = undefined;
}
json(res, result);
connection.release();
});
});
},
queryById: function (req, res, next) {
var id = +req.query.id;
pool.getConnection(function (err, connection) {
connection.query(sql.queryById, id, function (err, result) {
if(result ! =' ') {
var _result = result;
result = {
result: 'select'.data: _result
}
} else {
result = undefined;
}
json(res, result);
connection.release();
});
});
},
queryByName: function (req, res, next) {
var name = req.query.name;
pool.getConnection(function (err, connection) {
connection.query(sql.queryByName, name, function (err, result) {
if(result ! =' ') {
var _result = result;
result = {
result: 'select'.data: _result
}
} else {
result = undefined;
}
json(res, result);
connection.release();
});
});
},
queryAll: function (req, res, next) {
pool.getConnection(function (err, connection) {
connection.query(sql.queryAll, function (err, result) {
if(result ! =' ') {
var _result = result;
result = {
result: 'selectall'.data: _result
}
} else {
result = undefined;
}
json(res, result);
connection.release();
});
});
},
upload: function (req, res, next) {
var des_file = "uploadFiles/file/" + req.originalname;
fs.readFile(req.path, function (error, data) {
if (error) {
return console.error(error);
}
fs.writeFile(des_file, data, function (err) {
if (err) {
// Failed to receive
console.log("---------- failed to receive ----------\n");
console.log(err);
}else {
// Received successfully
// Delete cached files
fs.unlink(req.path, function(err){
if (err){
console.log('file:+req.path+'Delete failed! ');
return console.error(err); }})// Write file information to the database
var time = new Date().toJSON();
// Parameters passed from the front end
var addSqlParams = [
req.fieldname,
req.originalname,
req.filename,
req.encoding,
req.mimetype,
req.size,
des_file,
__dirname + '/' + req.path,
time
]
// Insert data
pool.getConnection(function (err, connection) {
connection.query(sql.upload, addSqlParams, function (err, result) {
if (err) {
return console.error(err);
}else {
var response = {
status:200.message: 'Upload successful! '.data: {id:result.insertId,
path:globalObj.rootDir+ '/' + des_file,
fileName:req.filename,
time:time,
type:req.mimetype,
size:req.size, } }; res.json( response ); connection.release(); }})})}})})})}};module.exports = userData;
Copy the code
GlobalObj, I created a config.js file in the root directory just to get the absolute path to the root directory, nothing else. Let’s move on.
const globalObj = {
rootDir:__dirname
}
module.exports = globalObj
Copy the code
Modify the routing file
//router/index.js
var express = require('express');
var router = express.Router();
var user = require('.. /modules/handle');
var multer = require('multer');
// Set the directory for the file cache
var upload = multer({ dest: './uploadFiles/tmp/'});
/* GET users listing. */
router.get('/'.function(req, res, next) {
res.render('index', { title: 'SQL for MySQL' });
});
router.get('/addUser'.function(req, res, next) {
user.add(req, res, next);
});
router.get('/queryAll'.function(req, res, next) {
user.queryAll(req, res, next);
});
router.get('/query'.function(req, res, next) {
user.queryById(req, res, next);
});
router.get('/queryName'.function(req, res, next) {
user.queryByName(req, res, next);
});
router.get('/deleteUser'.function(req, res, next) {
user.delete(req, res, next);
});
router.get('/update'.function(req, res, next) {
res.render('update');
});
router.post('/updateUser'.function(req, res, next) {
user.update(req, res, next);
});
// File upload
router.post('/upload', upload.array('file'),function(req, res, next) {
// File information
if (req.files[0]) {console.log("---------- Receive file ----------\n");
console.log(req.files[0]);
}
let reqData = req.files[0]
user.upload(reqData, res, next);
});
module.exports = router;
Copy the code
Modify the HTML file, just add an upload button or something. If YOU’re using CSS, it’s already all over the place.
<html lang="en">
<head>
<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>
<link rel="stylesheet" type="text/css" href="./index.css" />
</head>
<body>
<div class="handler">
<input type="text" id="searchValue" placeholder="Please enter your name for enquiry">
<button id="searchBtn">The query</button>
<button id="resetBtn">reset</button>
<button id="addBtn" class="primary">new</button>
</div>
<div class="table-box">
<table border="0" cellspacing="0" cellpadding="0" id="box">
</table>
</div>
<! -- Add pop-ups -->
<div id="modal">
<div class="dialog-box">
<div class="dialog-box__main">
<div class="main-item">
<label for="">The name</label>
<input type="text" placeholder="Please enter your name" id="nameValue">
</div>
<div class="main-item">
<label for="" >age</label>
<input type="text" placeholder="Please enter a number" id="ageValue">
</div>
<div class="main-item">
<label for="" >photo</label>
<div id="imgBox">
</div>
<div id="fileAdd">
</div>
<input type="file" id="fileBtn" value="Photos">
</div>
</div>
<div class="dialog-box__footer">
<button id="cancelBtn">cancel</button>
<button id="confirmBtn" class="primary">determine</button>
</div>
</div>
</div>
<! -->
<div id="tips">
</div>
<! -- Confirm the box -->
<div id="confirmModal">
<div class="confirm-box">
<h3 class="title">prompt</h3>
<div id="confirmMsg">Are you sure?</div>
<div class="dialog-box__footer">
<button id="confirmCancel">cancel</button>
<button id="confirmOK" class="primary">determine</button>
</div>
</div>
</div>
</body>
</html>
<script src="./index.js"> </script>
Copy the code
Index.js has also been changed to add some upload logic
function queryDom(name){
return document.querySelector(name)
}
let dialogBox = queryDom('.dialog-box')
let confirmModal = queryDom('#confirmModal')
let confirmMsg = queryDom('#confirmMsg')
let confirmCancel = queryDom('#confirmCancel')
let confirmOK = queryDom('#confirmOK')
let searchBtn = queryDom('#searchBtn')
let resetBtn = queryDom('#resetBtn')
let searchValue = queryDom('#searchValue')
let box = queryDom('#box')
let nameValue = queryDom('#nameValue')
let ageValue = queryDom('#ageValue')
let addBtn = queryDom('#addBtn')
let confirmBtn = queryDom('#confirmBtn')
let cancelBtn = queryDom('#cancelBtn')
let modal = queryDom('#modal')
let tipsBox = queryDom('#tips')
let delBtn = queryDom('.addBtn')
/* Upload image */
let fileBtn = document.getElementById('fileBtn')
let fileAdd = document.getElementById('fileAdd')
let imgBox = document.getElementById('imgBox')
// Specify a variable that controls whether to add or edit
let flag = 'add'
let gobj = {} // Temporarily store edit data
var imgObj = {}
// Query the list once when the page loads
window.onload = function () {
getList()
}
/ * -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- click event parts -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - * /
searchBtn.onclick = function () {
getListByName(searchValue.value)
}
/ / reset
resetBtn.onclick = function () {
searchValue.value = ' '
getList()
}
// Edit and delete
box.onclick = function (e) {
if (e.target.className.indexOf('updateBtn') >- 1) {
modal.style.display = 'block'
modal.style.opacity = 1
dialogBox.style.left = '50%'
flag = 'edit'
let obj = JSON.parse(e.target.getAttribute('data-item'))
gobj = obj
imgObj = {
id:obj.fileId,
path:obj.fileUrl,
}
imgBox.innerHTML = `<img src="${imgObj.path}" width="50px" style="margin-right:10px;" > `
detail(obj)
} else if (e.target.className.indexOf('delBtn') >- 1) {
let id = e.target.getAttribute('data-id')
confirmBox('This deletes the row. Are you sure? ').then(function(){
del(id)
}).catch(function(){
console.log('Cancel delete')}}}function detail(item) {
nameValue.value = item.name
ageValue.value = item.age
}
/ / new
addBtn.onclick = function () {
modal.style.display = 'block'
modal.style.opacity = 1
dialogBox.style.left = '50%'
flag = 'add'
nameValue.value = ' '
ageValue.value = ' '
imgObj = {}
imgBox.innerHTML = ' '
}
// File upload
fileBtn.onchange = function(e){
let file = e.target.files[0]
fileUpload(file,function(res){
imgBox.innerHTML = `<img src="${res.data.path}" width="50px" style="margin-right:10px;" > `
imgObj = res.data
})
}
// Click upload image
fileAdd.onclick = function(){
fileBtn.click()
}
/ / cancel
cancelBtn.onclick = function () {
setTimeout(function() {
modal.style.display = 'none'
}, 1000);
modal.style.opacity = 0
dialogBox.style.left = '-300px'
}
/ / sure
confirmBtn.onclick = function () {
// Check cannot be null
if(! ageValue.value||! nameValue.value||! imgObj.id){ tips.error('Cannot be empty')
return
}
// Check whether the age is a number
if(!/^\d*$/g.test(ageValue.value)){
tips.error('Age please enter a number')
return
}
setTimeout(function() {
modal.style.display = 'none'
}, 1000);
modal.style.opacity = 0
dialogBox.style.left = '-300px'
if (flag === 'add') {
add()
} else if (flag === 'edit') {
update(gobj.id)
}
}
/ * -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- click event parts -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - * /
/ * -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- request part -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - * /
// Delete data
function del(id) {
_ajax({
url: 'http://localhost:3000/deleteUser'.data: {
id: id,
},
success: function (res) {
if (res.code === '200') {
tips.success(res.msg)
getList()
} else {
tips.error(res.msg)
}
},
error: function (e) {
console.log(e, 'error')}}}// Get all data
function getList() {
_ajax({
url: 'http://localhost:3000/queryAll'.success: function (res) {
let resData = res.data || []
if (resData) {
renderTable(resData)
}
},
error: function (e) {
console.log(e, 'error')}}}// Query data by name
function getListByName(name) {
_ajax({
url: 'http://localhost:3000/queryName'.data: {
name: name
},
success: function (res) {
let resData = res.data || []
if (resData) {
renderTable(resData)
}
},
error: function (e) {
console.log(e, 'error')}}}// Add data
function add() {
_ajax({
url: 'http://localhost:3000/addUser'.data: {
name: nameValue.value,
age: ageValue.value,
fileId:imgObj.id,
fileUrl:imgObj.path,
},
success: function (res) {
if (res.code === '200') {
tips.success(res.msg)
getList()
} else {
tips.error(res.msg)
}
},
error: function (e) {
console.log(e, 'error')}}}// Update data
function update(id) {
_ajax({
url: 'http://localhost:3000/updateUser'.method: 'POST'.data: {
id: id,
name: nameValue.value,
age: ageValue.value,
fileId:imgObj.id,
fileUrl:imgObj.path,
},
success: function (res) {
if (res.code === '200') {
tips.success(res.msg)
getList()
} else {
tips.error(res.msg)
}
},
error: function (e) {
console.log(e, 'error')}}}/ * -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - requested part -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - * /
// Encapsulate render table functions
function renderTable(list){
// Empty the previous table
box.innerHTML = ' '
// Add a header
let headerTrNode = document.createElement('tr')
headerTrNode.innerHTML = X. ` < th > < / th > < th > id < / th > < th > name < / th > < th > age < / th > < th > photo < / th > < th > < / th > operation `
box.appendChild(headerTrNode)
// Render table body according to data
list.forEach((item,index) = >{
let trNode = document.createElement('tr')
trNode.innerHTML = `
<td>${index+1}</td>
<td>${item.id}</td>
<td>${item.name}</td>
<td>${item.age}</td>
<td>
<img src="${item.fileUrl}" width="50px">
</td>
<td >
<button class="updateBtn primary" data-item='The ${JSON.stringify(item)}'> edit < / button > & have spent <button class="delBtn danger" data-id="${item.id}</button> </td>
box.appendChild(trNode)
})
}
// Encapsulate the request function
function _ajax(option) {
let url = option.url || ' '
let method = option.method ? option.method.toUpperCase() : 'GET'
let data = option.data || null
// Change the request parameters to form format
var formData = []
for (var key in data) {
formData.push(' '.concat(key, '=', data[key]))
}
data = formData.join('&')
if (method === 'GET') {
url += location.search.length === 0 ? ' '.concat('? ', data) : ' '.concat('&', data)
}
let xhr = new XMLHttpRequest()
xhr.open(method, url, true)
// Set the response parameters to the format passed in or the default JSON format
xhr.responseType = option.responseType || 'json'
xhr.onreadystatechange = (a)= > {
if (xhr.readyState === 4) {
if (xhr.status === 200) {
option.success(xhr.response)
} else {
option.error()
}
}
}
if (method === 'POST') {
// Set the request format for sending data to form format
// xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded')
// Set the request format for sending data to JSON format
xhr.setRequestHeader('content-type'.'application/json');
}
xhr.send(method === 'POST' ? JSON.stringify(option.data) : null)}// File upload
function fileUpload(file,callback){
let url = "http://localhost:3000/upload";
let form = new FormData(); / / FormData object
form.append("file", file); Upload.array ('file')
let xhr = new XMLHttpRequest(); / / the XMLHttpRequest object
xhr.open("post", url, true); // Post mode. The URL is the server request address. True Specifies whether the request is processed asynchronously.
xhr.onreadystatechange = function(){
if(xhr.readyState === 4) {if(xhr.status === 200) {let resData = JSON.parse(xhr.responseText)
callback(resData)
}else{
console.log('Upload failed')
}
}
}
xhr.send(form); // Start uploading and send the form data
}
/* ---------------- tool function part -------------- */
// Encapsulate a hint function
function Tips() {
var loop
this.error = function (str, delay) {
if(loop){
clearTimeout(loop)
}
tipsBox.style.display = 'block'
tipsBox.style.background = '#ff6666'
tipsBox.innerHTML = str
loop = setTimeout((a)= > {
tipsBox.style.display = 'none'
}, delay || 3000)}this.success = function (str, delay) {
if(loop){
clearTimeout(loop)
}
tipsBox.style.display = 'block'
tipsBox.style.background = '#78d626'
tipsBox.innerHTML = str
loop = setTimeout((a)= > {
tipsBox.style.display = 'none'
}, delay || 3000)}}let tips = new Tips()
// Encapsulate a secondary confirmation frame
function confirmBox(msg){
msg = msg || 'Sure to delete? '
confirmMsg.innerHTML = msg
confirmModal.style.display = 'block'
return new Promise(function (resolve,reject) {
confirmOK.onclick = function(){
confirmModal.style.display = 'none'
resolve()
}
confirmCancel.onclick = function(){
confirmModal.style.display = 'none'
reject()
}
});
}
/* ---------------- tool function part -------------- */
Copy the code
And then I’m going to create a new folder in the root directory to store the files that I’ve uploaded
. | - uploadFiles | - file | -- TMP...Copy the code
And then restart the service
npm start
Copy the code
We can see that
The whole demo code, I put in my Github, can be directly used to run, do not need to like the above so laborious, above I just want to make a process, convenient to check later, is how to step by step.