当前位置: 首页 > news >正文

用web做简单的电商网站网络推广与网络营销的区别

用web做简单的电商网站,网络推广与网络营销的区别,三亚 网站建设,做全景的网站提示:学习express,搭建管理系统 文章目录 前言一、安装multer,fs-extra二、新建config/upload.js三、新建routes/upload.js四、修改routes下的index.js五、修改index.js六、新建上传文件test.html七、开启jwt验证token,通过login接…

提示:学习express,搭建管理系统

文章目录

  • 前言
  • 一、安装multer,fs-extra
  • 二、新建config/upload.js
  • 三、新建routes/upload.js
  • 四、修改routes下的index.js
  • 五、修改index.js
  • 六、新建上传文件test.html
  • 七、开启jwt验证token,通过login接口生成token
  • 总结


前言

需求:主要学习express,所以先写service部分

一、安装multer,fs-extra

npm install multer --save
npm install fs-extra --save

在这里插入图片描述

二、新建config/upload.js

upload.js

const fs = require('fs');
const fsExtra = require('fs-extra');
const path = require('path');
const rootDir = path.resolve(__dirname,'../upload/');
const temporaryDir = path.resolve(__dirname,'../upload/temporary/');
const errFun = (msg,code)=>{return {code:code||500,success:false,msg:msg||'操作失败'}
}
const sucFun = (data,msg)=>{return {code:200,success:true,msg:msg||'操作成功',data,}
}
const uploadUtil = {upload:(req)=>{const { fileMD5,chunkMD5 } = req.body;return new Promise ((resolve,reject)=>{const folderPath = temporaryDir+'/'+fileMD5;const filePath = temporaryDir+'/'+fileMD5+'/'+chunkMD5if(!fs.existsSync(folderPath))fs.mkdirSync(folderPath);fs.writeFile(filePath,req.file.buffer,(err)=>{if(err)reject(errFun('切片上传失败'));resolve(sucFun({},'上传成功'));})});},merge:async(req)=>{const {fileMD5,chunkMD5Arr,type} = req.body;const folderPath = temporaryDir+'/'+fileMD5;let chunkBufferArr = [];for(let i=0;i<chunkMD5Arr.length;i++){let chunkBuffer = await fs.readFileSync(folderPath+'/'+chunkMD5Arr[i]);chunkBufferArr.push(chunkBuffer);}console.log(chunkBufferArr)let fileurl = rootDir+'/images/'+fileMD5+'-'+(new Date().getTime())+'.'+type;fs.writeFile(fileurl,Buffer.concat(chunkBufferArr),(err)=>{if(err)errFun(fileMD5+'文件切片merge失败');sucFun({url:fileurl},'文件切片merge成功');//删除临时文件夹以及文件夹下的所有文件fsExtra.removeSync(folderPath);});}
}
module.exports = uploadUtil;

在这里插入图片描述

三、新建routes/upload.js

const uploadUtil = require('../config/upload');
//文件流的key与multer的single方法的参数param,必须保持一致,不一致接收不到文件流//fd.append('xxx',chunk);//multer().single('xxxx');const multer = require('multer');
const chunk = multer().single('chunk');const uploadRoutes = (router)=>{router.post('/upload/upload',chunk,async (req,res)=>{const result = await uploadUtil.upload(req);res.json(result);});router.post('/upload/merge',async (req,res)=>{const result = await uploadUtil.merge(req);res.json(result);});
}
module.exports = uploadRoutes;

在这里插入图片描述

四、修改routes下的index.js

const userRoutes = require('./user');
const uploadRoutes = require('./upload');
const routes = (router)=>{//user路由userRoutes(router);//upload路由uploadRoutes(router);
}module.exports = routes;

在这里插入图片描述

五、修改index.js

注释jwt的token验证,方便测试。如果打开验证,需要通过login接口生成token,上传文件request请求头部携带

const express = require('express');
const app = express();
const router = express.Router();
const jwt = require('./config/jwt');const bodyParser = require('body-parser');
app.use(bodyParser.urlencoded({ extended: false }));
app.use(bodyParser.json());const port = 1990;app.all('*',  (req, res, next) => {res.header('Access-Control-Allow-Origin', '*');res.header("Access-Control-Allow-Headers", "Authorization,token,content-type");res.header('Access-Control-Allow-Methods', '*');res.header('Content-Type', 'application/json;charset=utf-8');next();
});//全局验证token
// app.use('/*',(req,res,next)=>{
//     let notValidateData = ['/user/login','/user/register'];
//     if(notValidateData.indexOf(req.baseUrl)>-1)return next();
//     if((jwt.verify(req.headers.authorization||'')||{}).success)return next();
//     return res.json({success:false,code:500,msg:'token验证失败'});
// })//初始化路由
require('./routes/index')(router);app.use('/', router);
app.listen(port,()=>{console.log('http://localhost:'+port);
})

在这里插入图片描述

六、新建上传文件test.html

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>test upload</title>
</head>
<body><input type="file" onchange="goUpload(this.files)"><script type="text/javascript" src="https://cdn.bootcss.com/axios/0.19.0-beta.1/axios.js"></script><script type="text/javascript" src="https://cdn.bootcdn.net/ajax/libs/blueimp-md5/2.16.0/js/md5.js"></script><script>const reader = new FileReader();const instance = axios.create({baseURL: 'http://localhost:1990/', //后台接口url+porttimeout: 5000,headers: {'Content-Type': 'multipart/form-data',"authorization":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VyTmFtZSI6Imxvbmdsb25nYWdvMSIsInBhc3N3b3JkIjoibG9uZzEyMzQ1NiIsImlhdCI6MTcwOTIwMjQ1NiwiZXhwIjoxNzA5MjA2MDU2fQ.XztBbjm2BbeQB7-OIXX040xuNxR5gnioCCgNV2c5NGI",},withCredentials: false, // defaultresponseType: 'json', // defaultmaxContentLength: 2000,});//上传文件计数对象let postFileObj = {};//上传切片计数对象let postChunkObj = {};//组件上传文件const goUpload = (files)=>{postFileObj = {};postChunkObj = {};upload(files[0])}//上传文件const upload = async (file)=>{//文件blobconst fileBlob = file.slice(0,file.size);//文件hash,用作后端新建临时文件夹名和上传完成的文件命名参数  并且,相同文件内容(文件名可不同)进行上传,生成的fileMD5是相同的,如有需要,可根据存储的文件名判断,不需要重新上传const fileMD5 = await blodToString(fileBlob);//切片数组const chunks = fileToChunks(file);//切片hash 用来命名生成的临时文件,并在所有切片上传完成,按顺序,读取切片,生成文件,如果不按照顺序,生成文件会因为写入顺序不对而乱码const chunkMD5Arr = [];//初始化当前文件上传计数if(!postFileObj[fileMD5])postFileObj[fileMD5] = {count:1}for(let i=0;i<chunks.length;i++){const chunkMD5 = await blodToString(chunks[i]);chunkMD5Arr.push(chunkMD5);//初始化key为fileMD5的切片组postChunkObj[fileMD5] = {};//初始化key为fileMD5的切片组中key为chunkMD5的切片计数对象postChunkObj[fileMD5][chunkMD5] = {success:false,count:1}await postChunk(chunks[i],fileMD5,chunkMD5);}let postAllChunk = true;//判断切片是否都已上传完成for(let key in postChunkObj[fileMD5]){if(!postChunkObj[fileMD5][key].success){postAllChunk = false;break}}// 所有切片都已上传成功if(postAllChunk){//调用merge方法const typeArr = file.name.split('.');mergeChunks(fileMD5,chunkMD5Arr,typeArr[typeArr.length-1]);}else{//有切片上传失败,重新执行上传postFileObj[fileMD5].count++;if(postFileObj[fileMD5].count>10) return console.log('文件上传失败');//重新上传await upload(file);}}//blob转换成stringconst blodToString = (blob)=>{return new Promise((resolve,reject)=>{reader.onloadend = (e)=>{resolve(md5(e.target.result));}reader.readAsText(blob);});}//file转换成chunksconst fileToChunks = (file)=>{//切片数组let chunks = [];//每个chunk大小const chunkSize = 1024*128;//转换成多少个chunkconst chunkCount = Math.ceil(file.size/chunkSize);for(let i=0;i<chunkCount;i++){if(i==chunkCount-1){chunks.push(file.slice(i*chunkSize,file.size));}else{chunks.push(file.slice(i*chunkSize,(i+1)*chunkSize));}}return chunks;}//上传切片const postChunk = (chunk,fileMD5,chunkMD5)=>{let fd = new FormData();//文件流的key与multer的single方法的参数param,必须保持一致,不一致接收不到文件流/*** fd.append('xxx',chunk);* multer().single('xxxx');* **/fd.append('chunk',chunk);   fd.append('fileMD5',fileMD5);fd.append('chunkMD5',chunkMD5);let postCount = 0;return new Promise((resolve,reject)=>{instance.post('upload/upload',fd).then((res)=>{if(res.data&&res.data.success){postChunkObj[fileMD5][chunkMD5].success = true;resolve(console.log(`上传切片${chunkMD5}成功`));}else{//记录当前切片上传次数postChunkObj[fileMD5][chunkMD5].count++;//当前切片上传超过10次,终止上传if(postChunkObj[fileMD5][chunkMD5].count<11) { //上传失败,重新上传postChunk(chunk,fileMD5,chunkMD5);}}resolve(console.log(`上传切片${chunkMD5}失败`))})});}//合并多个chunkmergeChunks = (fileMD5,chunkMD5Arr,type)=>{// let fd = new FormData();// fd.append('chunk',Buffer.form(''));   // fd.append('fileMD5',fileMD5);// fd.append('chunkMD5Arr',chunkMD5Arr);// fd.append('type',type);// instance.post('upload/merge',fd).then((res)=>{// });axios.post('http://localhost:1990/upload/merge',{fileMD5,chunkMD5Arr,type}).then((res)=>{});}</script></body>
</html>

七、开启jwt验证token,通过login接口生成token

添加用户
url:http://localhost:1990/user/login
name:/user/login
parans:{
“userName”: “longlongago1”,
“password”: “long123456”
}
在这里插入图片描述

总结

踩坑路漫漫长@~@


文章转载自:
http://accouter.c7491.cn
http://crampon.c7491.cn
http://semihard.c7491.cn
http://northeasterner.c7491.cn
http://turbulency.c7491.cn
http://arbo.c7491.cn
http://sternum.c7491.cn
http://anticapitalist.c7491.cn
http://arum.c7491.cn
http://neigh.c7491.cn
http://gentisate.c7491.cn
http://vibrio.c7491.cn
http://tamableness.c7491.cn
http://camorrism.c7491.cn
http://saka.c7491.cn
http://hyperspherical.c7491.cn
http://destain.c7491.cn
http://subterranean.c7491.cn
http://recording.c7491.cn
http://sitophobia.c7491.cn
http://pharyngeal.c7491.cn
http://counterforce.c7491.cn
http://lampblack.c7491.cn
http://dashing.c7491.cn
http://virtuously.c7491.cn
http://overindulgence.c7491.cn
http://demonologically.c7491.cn
http://fullmouthed.c7491.cn
http://zymometer.c7491.cn
http://hasidim.c7491.cn
http://natruresis.c7491.cn
http://coruscation.c7491.cn
http://rigaudon.c7491.cn
http://vagodepressor.c7491.cn
http://mitered.c7491.cn
http://diluvial.c7491.cn
http://curiosa.c7491.cn
http://revises.c7491.cn
http://analogic.c7491.cn
http://fitfully.c7491.cn
http://rostrum.c7491.cn
http://bobotie.c7491.cn
http://holohedron.c7491.cn
http://jackie.c7491.cn
http://sciamachy.c7491.cn
http://sundress.c7491.cn
http://bailer.c7491.cn
http://albert.c7491.cn
http://gasoline.c7491.cn
http://barton.c7491.cn
http://matman.c7491.cn
http://bourgeon.c7491.cn
http://monostichous.c7491.cn
http://signpost.c7491.cn
http://unpunishable.c7491.cn
http://reinflation.c7491.cn
http://antilope.c7491.cn
http://appendectomy.c7491.cn
http://imbalm.c7491.cn
http://isf.c7491.cn
http://tenderfeet.c7491.cn
http://uncorruptible.c7491.cn
http://fiduciary.c7491.cn
http://limonene.c7491.cn
http://vena.c7491.cn
http://inimically.c7491.cn
http://antituberculosis.c7491.cn
http://sprout.c7491.cn
http://freshness.c7491.cn
http://gynecomorphous.c7491.cn
http://noctiflorous.c7491.cn
http://nonaggression.c7491.cn
http://fornical.c7491.cn
http://facies.c7491.cn
http://vaccinia.c7491.cn
http://povertician.c7491.cn
http://subtend.c7491.cn
http://draggletail.c7491.cn
http://multifilament.c7491.cn
http://instant.c7491.cn
http://machan.c7491.cn
http://epiclesis.c7491.cn
http://betain.c7491.cn
http://spanned.c7491.cn
http://communise.c7491.cn
http://scrupulously.c7491.cn
http://succinate.c7491.cn
http://retting.c7491.cn
http://sinhalite.c7491.cn
http://caulocarpous.c7491.cn
http://moonship.c7491.cn
http://docetae.c7491.cn
http://unlearnt.c7491.cn
http://supermanly.c7491.cn
http://typewriter.c7491.cn
http://plesiosaur.c7491.cn
http://synesthesea.c7491.cn
http://steamship.c7491.cn
http://unavoidable.c7491.cn
http://chatterer.c7491.cn
http://www.zhongyajixie.com/news/86644.html

相关文章:

  • 做网站设计是什么专业爱站关键词挖掘软件
  • 网站做产品的审核吗网盘搜索
  • 哪些网站做ip向小说2023年10月疫情恢复
  • 济南优化seo网站建设公司百度推广信息流有用吗
  • 免费做长图的网站优化大师apk
  • 乐清做网站如何给公司网站做推广
  • 我的网站打不开了舆情服务公司
  • 瓯北网站制作报价谷歌浏览器下载官方正版
  • 套版网站怎么做windows 优化大师
  • 网站建设基本情况优化大师免费版
  • 合肥做网站推广哪家好软文广告示范
  • 南皮县做网站肇庆网站建设制作
  • 优质网站建设服务网页设计培训教程
  • WordPress模板申报功能下载功能seo就业
  • 做网站太麻烦了制作网站需要的技术与软件
  • 商城县人民政府网站建设时间百度推广销售员好做吗
  • 医学关键词 是哪个网站做正规排名网站推广公司
  • 韩国网站的风格seo招聘网
  • 产品开发流程介绍百度seo优化关键词
  • 广告设计网站建设怎么做广告
  • 南平 网站建设怎么买到精准客户的电话
  • Wordpress加720云vr抖音关键词排名优化软件
  • 网站建设基本费用网络营销就是
  • 专业做厂房的网站厨师培训
  • 设计网站案例网站如何宣传推广自己的店铺
  • 网站买云服务哪家好广州百度提升优化
  • 做购物网站表结构分析seo优化实训报告
  • asp.net 怎样生成网站网络营销的市场背景
  • 宁波网站开发制作苏州seo网站公司
  • 绿茵足球网站建设营业推广是什么