上传的图片/头像有两种方案上传
第一种我们不对图片做处理直接上传到服务器端,把图片上传到服务器的img文件夹当中,然后我们把图片的地址信息存储在数据库当中,用图片的时候我们直接调用地址
第二种方案是我们在客户端(因为我们写出来的产品是客户肉眼可见,所以前端又称客户端)把图片转换为base64的格式,然后把图片的base64的内容直接存储在数据库当中,需要用到图片的时候我们直接把数据库内部的图片的base64信息,调用到前端的img标签的src属性当中.方案二我会在头像上传功能的详细解析2当中细细给大家分解实现过程.今天先讲解分析方案1的实现过程.

实现头像上传功能,我们需要用到上传的模块multer模块

实现图片上传知识储备:前端方面知识储备:第一我们需要懂FormData对象(之前没接触过图片上传的百分之七八十的人都应该不懂,所以我会在本文章的最后面去讲解FormData对象的相关知识.),第二我们要会用jQuery,第三我们要用到ajax请求。后端方面(也就是node.js方面的东西):第一我们要懂multer模块,第二我们要懂fs模块
,第三我们最基础的静态资源服务器至少需要懂。
(不管是方案二还是方案一)上传头像我们都离不开对multer模块的使用
俗话说:“工欲善其事,必先利其器。”我们第一步当然是先下载安装multer模块
使用的指令如下↓
npm install multer
安装完成后会看到package.json文件下面有相关依赖,如下图片显示的multer:^1.4.2

以下是后端代码node.js的详解以及注释

//我引入multer模块
var express=require("express")
var bodyParse=require("body-parser")
var path=require("path")
var fs=require("fs")
var multer  = require('multer')
// 创建一个multer中间件对象,注意一定别忘了要创建multer中间件对象
var upload = multer({})
var app=express()
// 开启静态资源服务器,访问图片的地址就是http://localhost:3000/img/hh0.5530300908602812.jpeg
app.use(express.static("./public"))
// 注意:上传图片我们在前端发请求的时候必须要用post请求方式
// 如下我 们使用upload这个中间件,我们使用.single("xixi")方法去定义上传图片字段的属性名为xixi,single方法定义只能单文件上传图片
// 如果想多文件上传(图片)我们就得使用.array('photos', 12)第一个参数表示字段名,第二个参数表示限制上传多少个文件,填数字
// 单文件上传我们接受文件信息用req.file,多文件上传我们用req.files去接收
app.post("/file",upload.single("xixi"),(req,res)=>{// req.file表示上传文件信息,默认是不存在的,只有被multer中间件处理过之后才有,如下我们打印//上面这句话的意思简而言之,就是你发起post上传图片的请求了,有图片上传了才能打印出req.file的信息来console.log(req.file);var {buffer,mimetype,encoding,originalname,fieldname,size}=req.file//req.file是一个对象,它里面的buffer属性就是我们要写入文件夹的图片// 将buffer写入到文件内部,为了防止后面的图片文件覆盖前面的图片文件,所以我们要使用时间戳让文件名无法重复// 判断尺寸size表示图片的大小console.log(size);if(size>=5000000){return res.send({err:-1,mgs:"图片尺寸过大"})}// 限制图片文件格式类型 1.前端判断  2.后端判断var typs=["jpg","gif","png","jpeg"]var extName=mimetype.split("/")[1]if(typs.indexOf(extName)===-1){return res.send({err:-2,mgs:"图片类型错误!"})}var t=Math.random()var ext=req.file.mimetype.split("/")[1]// 然后用fs模块写入图片到img文件夹下fs.writeFile(path.join(__dirname,"./public/img/"+t+"."+ext),buffer,(err)=>{if(err){console.log(err);res.send({jg:"图片上传失败!"})}else{res.send({jg:"图片上传成功!",path:`/img/${t}.${extName}`})}})
})
app.listen(3000,()=>{console.log("服务器端口3000启动成功!");
})

下面是前端的html代码

<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>文件上传小案例</title>
</head>
<body><input type="file" id="file" multiple="multiple"><div><button id="cs">请选择上传一张图片</button></div><p>缩略图:</p><img src="" alt="" class="slt">
</body>
<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.js"></script>
<script>// 1.用户选择图片// 2.通过ajax上传图片cs.onclick = function () {// document.querySelector("#file").files是一个对象,表示列表清单var file1 = document.querySelector("#file").filesconsole.log(file1);//我们用对象的中括号语法获取图片信息var file = document.querySelector("#file").files[0]// console.log(Object.prototype.toString.call(file));console.log(file);// 图片上传的格式不是表单x-www-form-urlencoded// 也不是json格式// 而是formdata格式  // 所以我们要将图片信息转化成到formdata对象当中// 如下我们new创建一个FormData对象// 使用内置构造函数创建的对象,new出来的 FormData对象跟普通的对象不同。// 如果 想在FormData对象内部添加字段就要用到append()方法// append()方法有两个参数第一个是字段属性名,参数二为字段属性值var data = new FormData()// key值跟接口统一注意了,这一点很重要,为什么我给大家先分析node.js的后端代码也是这个原因,//因为我们append方法的参数一需要与在后端用single("xixi")方法设置好的xixi字段名统一//后台给你写的是xixi你就不能用别的字段去传否则就会上传失败【重点重点重点重要的事情说三遍】data.append("xixi", file)// FormData对象 默认打印不是我们想要的列表信息 通过get方法获取才可以获取到比如下面的data.get("xixi")        console.log("没有使用get方法打印为FormData→", data);console.log("通过get方法获取后→", data.get("xixi"));$.ajax({// 请求路径urlurl: "http://localhost:3000/file",// 请求类型typetype: "POST",// 请求信息中携带的字段数据data,也就是FormData对象data: data,// 发起ajax请求默认不是表单就是json格式,上传图片时我们都不需要,所以就取消格式contentType:false,// 设置processData:false是因为jQuery会默认将数据进行格式化处理,我们图片上传不需要就取消默认processData:false,// 回调函数:// 回调函数中也有分类:// 1.请求成功的时候;→success// 参数不用记:1.responseText 2.状态 3.xhr对象;success: function (res, state, arguments) {console.log(arguments)console.log(state)console.log("成功", res)var body=document.querySelector("body")var h1=document.createElement("h1")h1.innerHTML=resbody.appendChild(h1)var {jg,path}=resconsole.log(jg,path);if(jg=="图片上传成功!"){$(".slt").attr("src",path)alert(jg)}},// 2.请求完成的时候;→completecomplete:function(xhr,state){console.log(1)console.log("完成",xhr,state)},// 3.请求失败的时候;→errorerror:function(xhr,state,errmsg){console.log("失败:error",xhr,state,errmsg,arguments)},// 根据状态码处理异常情况// 传参的形式比较特别:以一个对象的形式出现// statusCode:{状态码:状态码下执行的函数}statusCode:{// 404状态码说明:服务器找不到你请求的URL,地址错误.404:function(){alert("抱歉,您的页面丢失了")},// 500状态码说明:服务器内部错误,后端代码写错了.500:function(){alert("抱歉,我们的服务器爆炸了")},// 403状态码:说明服务器拒绝了你的请求.403:function(){alert("抱歉,服务器拒绝访问")},}})}
</script>
</html>

结合上面的html文档以及node.js当中的js文件我们就可以完美的实现,图片上传了。

有些小伙伴可能不了解FormData对象的那么我下面给大家分析一下给大家扩展一些FormData对象的小知识

利用FormData对象,你可以使用一系列的键值对来模拟一个完整的表单,然后使用XMLHttpRequest发送这个"表单".创建一个FormData对象
你可以先创建一个空的FormData对象,然后使用append()方法向该对象里添加字段,如下:var oMyForm = new FormData();oMyForm.append("username", "Groucho");
oMyForm.append("accountnum", 123456);// 数字123456被立即转换成字符串"123456"
// fileInputElement中已经包含了用户所选择的文件
oMyForm.append("userfile", fileInputElement.files[0]);var oFileBody = "<a id="a"><b id="b">hey!</b></a>";// Blob对象包含的文件内容
var oBlob = new Blob([oFileBody], { type: "text/xml"});oMyForm.append("webmasterfile", oBlob);var oReq = new XMLHttpRequest();
oReq.open("POST", "http://foo.com/submitform.php");
oReq.send(oMyForm);
注: 字段"userfile"和"webmasterfile"的值都包含了一个文件.通过 FormData.append()方法赋给字段"accountnum"的数字被自动转换为字符(字段的值可以是一个Blob对象,一个File对象,或者一个字符串,剩下其他类型的值都会被自动转换成字符串).
在该例子中,我们创建了一个名为oMyForm的FormData对象,该对象中包含了名为"username", "accountnum", "userfile" 以及 "webmasterfile"的字段名,然后使用XMLHttpRequest的send()方法把这些数据发送了出去."webmasterfile"字段的值不是一个字符串,还是一个Blob对象.使用HTML表单来初始化一个FormData对象
可以用一个已有的<form>元素来初始化FormData对象,只需要把这个form元素作为参数传入FormData构造函数即可:var newFormData = new FormData(someFormElement);
例如:var formElement = document.getElementById("myFormElement");
var oReq = new XMLHttpRequest();
oReq.open("POST", "submitform.php");
oReq.send(new FormData(formElement));
你还可以在已有表单数据的基础上,继续添加新的键值对,如下:var formElement = document.getElementById("myFormElement");
formData = new FormData(formElement);
formData.append("serialnumber", serialNumber++);
oReq.send(formData);
你可以通过这种方式添加一些不想让用户编辑的固定字段,然后再发送.使用FormData对象发送文件
你还可以使用FormData来发送二进制文件.首先在HTML中要有一个包含了文件输入框的form元素:<form enctype="multipart/form-data" method="post" name="fileinfo"><label>Your email address:</label><input type="email" autocomplete="on" autofocus name="userid" placeholder="email" required size="32" maxlength="64" /><br /><label>Custom file label:</label><input type="text" name="filelabel" size="12" maxlength="32" /><br /><label>File to stash:</label><input type="file" name="file" required />
</form>
<div id="output"></div>
<a href="javascript:sendForm()">Stash the file!</a>
然后你就可以使用下面的代码来异步的上传用户所选择的文件:function sendForm() {var oOutput = document.getElementById("output");var oData = new FormData(document.forms.namedItem("fileinfo"));oData.append("CustomField", "This is some extra data");var oReq = new XMLHttpRequest();oReq.open("POST", "stash.php", true);oReq.onload = function(oEvent) {if (oReq.status == 200) {oOutput.innerHTML = "Uploaded!";} else {oOutput.innerHTML = "Error " + oReq.status + " occurred uploading your file.<br \/>";}};oReq.send(oData);
}
你还可以不借助HTML表单,直接向FormData对象中添加一个File对象或者一个Blob对象:data.append("myfile", myBlob);
如果FormData对象中的某个字段值是一个Blob对象,则在发送http请求时,代表该Blob对象所包含文件的文件名的"Content-Disposition"请求头的值在不同的浏览器下有所不同,Firefox使用了固定的字符串"blob,"而Chrome使用了一个随机字符串.你还可以使用jQuery来发送FormData,但必须要正确的设置相关选项:var fd = new FormData(document.getElementById("fileinfo"));
fd.append("CustomField", "This is some extra data");
$.ajax({url: "stash.php",type: "POST",data: fd,processData: false, // 告诉jQuery不要去处理发送的数据contentType: false  // 告诉jQuery不要去设置Content-Type请求头
一.创建一个formData对象实例的方式
1、创建一个空对象var formData = new FormData();//通过append方法添加数据
1
2、使用已有表单来初始化对象//表单示例
<form id="myForm" action="" method="post"><input type="text" name="name">名字<input type="password" name="psw">密码<input type="submit" value="提交">
</form>//方法示例
// 获取页面已有的一个form表单
var form = document.getElementById("myForm");
// 用表单来初始化
var formData = new FormData(form);
// 我们可以根据name来访问表单中的字段
var name = formData.get("name"); // 获取名字
var psw = formData.get("psw"); // 获取密码
// 当然也可以在此基础上,添加其他数据
formData.append("token","kshdfiwi3rh");二. 操作方法
formData里面存储的数据是以健值对的形式存在的,key是唯一的,一个key可能对应多个value。
如果是使用表单初始化,每一个表单字段对应一条数据,它们的HTML name属性即为key值,它们value属性对应value值。
1.获取值//通过get(key)/getAll(key)来获取对应的value
formData.get("name"); // 获取key为name的第一个值
formData.get("name"); // 返回一个数组,获取key为name的所有值2 添加数据//通过append(key, value)来添加数据,如果指定的key不存在则会新增一条数据,如果key存在,则添加到数据的末尾
formData.append("k1", "v1");
formData.append("k1", "v2");
formData.append("k1", "v3");获取值时方式及结果如下formData.get("k1"); // "v1"
formData.getAll("k1"); // ["v1","v2","v3"]
3.设置修改数据//set(key, value)来设置修改数据,如果指定的key不存在则会新增一条,如果存在,则会修改对应的value值
formData.append("k1", "v1");
formData.set("k1", "1");
formData.getAll("k1"); // ["1"]
4.判断是否存在对应数据//has(key)来判断是否对应的key值
formData.append("k1", "v1");
formData.append("k2",null);formData.has("k1"); // true
formData.has("k2"); // true
formData.has("k3"); // false
5.删除数据//delete(key)删除数据
formData.append("k1", "v1");
formData.append("k1", "v2");
formData.append("k1", "v1");
formData.delete("k1");formData.getAll("k1"); // []三.JQuery实例
//添加数据方式见上二。
//processData: false, contentType: false,多用来处理异步上传二进制文件。$.ajax({url: 'xxx',type: 'POST',data: formData,                    // 上传formdata封装的数据dataType: 'JSON',cache: false,                      // 不缓存processData: false,                // jQuery不要去处理发送的数据contentType: false,                // jQuery不要去设置Content-Type请求头success:function (data) {           //成功回调console.log(data);}
});
/*** 将以base64的图片url数据转换为Blob文件格式* @param urlData 用url方式表示的base64图片*/
function convertBase64UrlToBlob(urlData) {var bytes = window.atob(urlData.split(',')[1]); //去掉url的头,并转换为byte//处理异常,将ascii码小于0的转换为大于0var ab = new ArrayBuffer(bytes.length);var ia = new Uint8Array(ab);for(var i = 0; i < bytes.length; i++) {ia[i] = bytes.charCodeAt(i);}return new Blob([ab], {type: 'image/png'});
}

前端头像上传功能实现之普通图片/头像上传 详细解析1【扩展知识FormData对象】相关推荐

  1. 前端头像上传功能实现之base64图片/头像上传 详细解析2【扩展知识FileReader对象】

    将图片变成base64字符串 base64是一种数据格式 就是一个字符串可以当图片来使用 // base64之将图片在前端变为base64格式 1.先获取图片 2.FileReader对象将图片进行转 ...

  2. 使用sun.net.ftp.FtpClient进行上传功能开发,在jdk1.7上不适用问题的解决

    使用sun.net.ftp.FtpClient进行上传功能开发,在jdk1.7上不适用问题的解决 参考文章: (1)使用sun.net.ftp.FtpClient进行上传功能开发,在jdk1.7上不适 ...

  3. 世界上第一台计算机高清图片,世界上最强大的数码相机:一张照片32亿像素,相当于378块4K超高清电视屏...

    世界上最大的数码相机能够拍摄32亿像素的照片,这是有史以来最大的单拍照片.这架相机计划在2021年被转移到维拉·鲁宾天文台(Rubin Observatory),该天文台是为"时间和空间遗产 ...

  4. php layui ajax多图上传,Laravel+Layer实现图片上传功能(整理篇)

    ♩ 背景 昨天在自己的 Laravel5.5 框架项目中,希望集成 Layer 的图片上传功能 但是在 ajax(POST) 提交请求时,一直显示 500 报错 ♪ 分析 ⒈ 问题所在 最后将核心代码 ...

  5. 实现HTTP协议Get、Post和文件上传功能——使用WinHttp接口实现

    在<使用WinHttp接口实现HTTP协议Get.Post和文件上传功能>一文中,我已经比较详细地讲解了如何使用WinHttp接口实现各种协议.在最近的代码梳理中,我觉得Post和文件上传 ...

  6. Vimeo上传功能中的SSRF

    前言 Vimeo是一个高清视频播客网站,与大多数类似的视频分享网站不同,Vimeo允许上传1280X700的高清视频,上传后Vimeo会自动转码为高清视频,源视频文件可以自由下载,它达到了真正的高清视 ...

  7. 附件上传功能测试用例

    转载自:https://blog.csdn.net/u011159607/article/details/80144142 序号 测试用例名称 测试用例描述 步骤 预期结果 说明 1 附件上传-文件命 ...

  8. Web开发中图片上传功能总结

    图片上传功能总结   1.添加文件上传所需jar包(commons-io-1.4.jar和commons-fileupload-1.1.1.jar)   2.在form表单上添加自带属性 enctyp ...

  9. jquery实现截取pc图片_Cropper.js 实现裁剪图片并上传(PC端)

    由于之前做项目的时候有需求是需要实现裁剪图片来做头像并上传到服务器,所以上网查询了很多资料,也试用了许多案例,发现cropper插件裁剪是比较完善的,所以结合之前的使用情况,编写了此案例.本案例是参考 ...

最新文章

  1. 去哪儿网笔试题——取出第一个重复的字符
  2. 论文浅尝 - SWJ | 基于知识图谱和注意力图卷积神经网络的可解释零样本学习
  3. 在Linux下使用Vim编写C++
  4. 【JMX】JMX 远程 连接 The client has been closed
  5. php 同步退出,Ucenter 的同步登录与同步退出
  6. hive报错(1)MoveTask
  7. E 帮 SeSe 的一篇示例
  8. 计算机网络基础B试题及答案,计算机网络基础试题及答案2
  9. python菜鸟教程w-【读书】Django教程(菜鸟教程)
  10. Lambda表达式与函数式接口详解
  11. 如何在服务器发布网站
  12. python中tan函数如何表示_Python入门之三角函数tan()函数实例详解
  13. 荣耀4a鸿蒙,华为 Plan B 揭开面纱:鸿蒙要超越安卓?小米 OPPO 们买单吗?
  14. ubuntu各种实践笔记
  15. 使用TIMESTAMPDIFF计算两个时间戳之间的时间间隔
  16. 搭建Genero BDL环境-安装篇
  17. 算力智库2021隐私计算论坛圆满落幕,隐私计算落地会长出怎样的新商业模式?
  18. UNIX网络套接字相关总结
  19. 电影▍更多的《复仇者联盟4:终局之战》剧透描述了令人心碎的超级英雄死亡...
  20. iphone试用手记

热门文章

  1. 【speach】语音信号基础
  2. 【图像识别】基于主成分分析算法实现人脸二维码识别matlab代码
  3. android 友盟渠道号,获取友盟渠道号
  4. jsoup爬取王者荣耀所有英雄背景图片
  5. 02 【版本控制命令】
  6. 任务3-1 基于控制台的购书系统
  7. 警惕“电子发票”邮件,多家企业中招
  8. css清除浮动的几种方式
  9. .NET6 使用 AutoFac (落地)
  10. LiteOS 学习第一篇