如何利用原生JS实现图片预览加上传(前后端交互)

目录
  • 前言
  • 效果大致如下
  • 前端代码
  • 后端代码
  • 总结

前言

最近在写vue项目的时候发现了个Vant的一个upload的图片上传的组件,就好奇了一下下,于是萌生了一个自己手写一个图片上传的组件的想法,您猜怎么着,还真给我实现了,那今天就和大家分享一下,大家有兴趣的可以了解一下啦,写进项目中可能会是个加分点哦!!

我们知道文件上传是需要前后端交互的,所以我这边给出前后端代码。 文件上传大致分为以下几个步骤

  • 前端文件选择上传的文件类型
  • 拿到文件信息
  • 将选择的文件(视频或图片)在前端页面预览出来
  • 将文件发上传到后端服务器
  • 客户端能够访问到上传到服务器端的文件

效果大致如下

前端代码

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<style>
.button{
margin-right: 20px;
}
#preview {
display: flex;
flex-wrap: wrap;
width: 1500px;
padding: 0 10px;
justify-content: start;
}
.icon-po {
overflow: hidden;
position: relative;
width: 300px;
height: 300px;
margin-right: 20px;
margin-top: 20px;
}
.icon-close {
position: absolute;
right: 5%;
top: 5%;
width: 30px;
height: 30px;
border-radius: 50%;
background-color: red;
color: #fff;
font-size: 12px;
display: flex;
align-items: center;
justify-content: center;
}
.pic{
width: 300px;
height: 300px;
}
</style>
</head>
<body>
选择文件(允许多文件):
<input type="file" id="f1" multiple> //multiple开启多选
<button type="button" class="button" id="btn-submit">预览图片</button>
<button type="button" id="complate">上传图片</button>
<div id="preview"></div>
<br />
<script>
let e = 0
let fd = new FormData() //文件传输一定要使用ForData对象
let fL = []
function submitUpload() {
let fileList = document.getElementById('f1').files
for (let i = 0; i < fileList.length; i++) {
fL.push(fileList[i])
}
//渲染出图片
//FileReader 读取文件的方式为readAsDataURL时会触发
function readAndPreview(file) {
// 确保 `file.name` 符合我们要求的扩展名
if (/\.(jpe?g|png|gif|mp4)$/i.test(file.name)) {
//FileReader 对象允许Web应用程序异步读取存储在用户计算机上的文件
//(或原始数据缓冲区)的内容
//这里是读取到input返回出来的fileList中文件
var reader = new FileReader();
//该事件在FileReader对象读取操作完成时触发
reader.addEventListener("load", function () {
//创建出两个div 一个用做父容器 一个做删除按钮
var div1 = document.createElement('div');
var div2 = document.createElement('div');
//创建一个Image Dom 用来做渲染图片
var dom = new Image() //当然要是想渲染视频的话就创建一个video标签就好啦
//给创建的Dom添加类名用于设计样式
div1.className = 'icon-po'
div2.className = 'icon-close'
div2.innerHTML = 'X'
dom.className = 'pic
//给生成的每个图片盒子添加index属性
div1.index = div2.index = e
e++
//给删除按钮添加上点击事件
div2.onclick = (e) => {
console.log(e.target.index)
div1.remove()
fL.splice(e.target.index, 1, "")
console.log(fL);
}
//设置img的样式
dom.width = 300;
dom.height = 300;
dom.title = file.name;
//该 result属性包含作为数据的数据: URL将文件的数据表示为 base64 编码的字符串。
dom.src = this.result;
//将创建出的dom添加进对应的dom中去
div1.appendChild(dom)
div1.appendChild(div2)
preview.appendChild(div1);
}, false);
//调用readAsDataURL()方法拿到result
reader.readAsDataURL(file);
}
}
//拿到input中的fileList中的文件对象进行渲染出图片
if (fileList) {
[].forEach.call(fileList, readAndPreview);
}
if (!fileList.length) {
alert('请选择文件')
return
}
}

function complate() {
//筛选出未删除的文件
fL.forEach(async (item) => {
if (typeof item === "string") {
console.log(item);
} else {
fd.append('files', item)//将没有别删除的文件加入到FormData对象中
}
})
//向后端发送请求
let xhr = new XMLHttpRequest()
xhr.open('POST', 'http://localhost:3007/', true)
xhr.send(fd)
xhr.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
let obj = JSON.parse(xhr.responseText)
console.log(obj);
}
}
}
document.getElementById('btn-submit').addEventListener('click', submitUpload)
document.getElementById('complate').addEventListener('click', complate)
</script>
</body>
</html>

后端代码

/**
 * 服务入口
 */
var koaStatic = require('koa-static');
var path = require('path');
var koaBody = require('koa-body');
var fs = require('fs');
var Koa = require('koa2');
var cors = require('koa2-cors') //解决跨域

var app = new Koa();
var port = process.env.PORT || '3007';
var uploadHost = `http://localhost:3001/uploads/`;
app.use(cors())
app.use(koaBody({
  //koa-body 是一个可以帮助解析 http 中 body 的部分的中间件,包括 json、表单、文本、文件等。
  formidable: {
    //设置文件的默认保存目录,不设置则保存在系统临时目录下
    uploadDir: path.resolve(__dirname, './static')
  },
  multipart: true // 支持文件上传
}));
app.use(koaStatic(
  //让我们更加快速访问服务中的静态资源
  path.resolve(__dirname, './static')
));
//二次处理文件,修改名称
app.use((ctx) => {
  console.log(ctx.request.files);
  var files = ctx.request.files.files;//得到上传文件的数组
  var result = [];
  console.log(files);
  let baseUrl = 'http://192.168.10.4:3007/'
  if (!Array.isArray(files)) {//单文件上传容错
    files = [files];
  }
  files && files.forEach(item => {
    var path = item.path.replace(/\\/g, '/');
    var fname = item.name;//原文件名称
    var nextPath = path + fname;
    if (item.size > 0 && path) {
      //得到扩展名
      var extArr = fname.split('.');
      var ext = extArr[extArr.length - 1];
      var nextPath = path + '.' + ext;
      //重命名文件
      fs.renameSync(path, nextPath);
      console.log(baseUrl + nextPath.slice(nextPath.lastIndexOf('/') + 1))
      result.push(baseUrl + nextPath.slice(nextPath.lastIndexOf('/') + 1));
    }
  });
  ctx.body = {//向前端返回图片上传后的地址
         "fileUrl":`${JSON.stringify(result)}`
     };
})

app.listen(port, () => {
  console.log('服务已启动3007');
})

总结

代码我都做好详细注释啦,使用到的官方对象的作用我也给你总结出来了给你们偷个懒!!相信大家花点时间看一下就能懂啦,最后我再叨叨几句~

  • 前端
  • js使用input type ="file"可以上传文件
  • 读取文件完成后创建出几个DOM用来预览图片,配置好相应的功能需求
  • FileReader 对象允许Web应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,使用 [File] 或 [Blob] 对象指定要读取的文件或数据。
  • readAsDataURL 方法会读取指定的 [Blob]/Blob) 或 [File] 对象。读取操作完成的时候,[readyState] 会变成已完成DONE,并触发 loadend (en-US) 事件,同时 [result] 属性将包含一个data:URL格式的字符串(base64编码)以表示所读取文件的内容。
  • FormData接口提供了一种方法来轻松构造一组表示表单字段及其值的键/值对,然后可以使用该[XMLHttpRequest.send()]方法向后端发送文件。
  • 后端
  • 后端这里是使用Koa写的
  • 安装koa2-cors防止跨域
  • 安装koa-body拿到前端传来的文件,并存在相应的目录下
  • 安装Koa-static然后端更加方便的访问到上传的文件地址

到此这篇关于如何利用原生JS实现图片预览加上传的文章就介绍到这了,更多相关JS实现图片预览上传内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!

(0)

相关推荐

  • js图片上传前预览功能(兼容所有浏览器)

    网上找到的一份文件上传前预览的代码,转自JavaScript 图片的上传前预览(兼容所有浏览器) <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html;charset=utf-8" /> <style type="text/css"> #preview, .img, img { w

  • js 上传图片预览问题

    最近也经常遇到浏览器兼容的问题,昨天遇到上传图片预览问题,发现IE8和火狐不能显示,弄了很久,早上终于解决了很高兴.故跟大家分享下,我也多是网上找的,自己总结的一下,希望对大家有点帮助. 我们一般根据IE6.IE7进行开发的时候写图片预览的代码是: 复制代码 代码如下: document.getElementById("img").src = document.getElementById("file").value; 还有一种方式 复制代码 代码如下: <d

  • JS实现上传图片的三种方法并实现预览图片功能

    在常见的用户注册页面,需要用户在本地选择一张图片作为头像,并同时预览. 常见的思路有两种:一是将图片上传至服务器的临时文件夹中,并返回该图片的url,然后渲染在html页面:另一种思路是,直接在本地内存中预览图片,用户确认提交后再上传至服务器保存. 这两种方法各有利弊,方法一很明显,浪费流量和服务器资源:方法二则加重了浏览器的负担,并且对浏览器的兼容性要求更高(在某些低版本中的IE浏览器不支持). 以下是实现上述思路的方法: 1. 模板文件 <!DOCTYPE html> <html l

  • js实现上传图片之上传前预览图片

    上传图片对图片进行一下预览,可以了解图片上传后大概会是什么样子,此功能用js实现,然后在fileupload控件的change事件中调用,这样当用fileupload选择完图片以后,图片就会自动显示出来了.功能很简单,却很实用. 预览图片的js代码: 复制代码 代码如下: <script type="text/javascript"> function setImagePreview(docObj,localImagId,imgObjPreview) { if(docObj

  • 上传图片预览JS脚本 Input file图片预览的实现示例

    在深圳做项目的时候,需要一个用户上传头像预览的功能!是在网上找了好多,都不太满意.要么是flash的,要么是Ajax上传后返回图片路径的,要么压根就是不能用的.幸运的是在这个项目以前有人写过一个图片预览的功能,还被我给翻了出来,在这里做个记录,方便自己以后用,也方便其他需要的朋友! 代码很简单,如下: <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/

  • Javascript图片上传前的本地预览实例

    图片的上传预览功能主要用于图片上传前的一个效果的预览,目前主流的方法主要有js,jquery与flash实现,但我们一般都会使用js来实现图片上传预览功能,下面来看一个例子. 原理: 分为两步:当上传图片的input被触发并选择本地图片之后获取要上传的图片这个对象的URL(对象URL):把对象URL赋值给事先写好的img标签的src属性即可把图片显示出来. 在这里,我们需要了解Javascript里File对象.Blob对象和window.URL.createObjectURL()方法. Fil

  • js实现图片上传预览原理分析

    目前网上有很多支持图片上传时进行预览的插件,功能完备,界面优雅,使用起来也很方便.一直以来也就只是用用,没有想过这些插件背后的实现原理.趁着今天有点时间,也来学习学习. 追根溯源 设想 一开始,按照我的思路,预览可能是这么来实现的.本地选中一张图片,嵌入html的同时会显示图片的本地的绝对路径,然后通过js简单的进行设置,应该就可以实现预览效果了. 但是实际上,目前只有低版本的IE浏览器才能实现这么个效果.究其原因是浏览器厂商为了进一步强化安全,限制了file标签直接读取本地路径的能力,在HTM

  • JS上传前预览图片实例

    预览图片的js代码: 复制代码 代码如下: <script type="text/javascript">        function setImagePreview(docObj,localImagId,imgObjPreview)         {            if(docObj.files && docObj.files[0])            {                //火狐下,直接设img属性            

  • js实现图片上传并预览功能

    本文为大家分享了js实现图片上传并预览的具体代码,供大家参考,具体内容如下 思路:完成这个功能,首先需要美化上传图片的按钮,然后添加一个<img/>标签,在图片上传之后,用新图片的src替换原来<img/>标签中的src. 如下图所示,是原始的按钮样式: 美化步骤: (1)将上传图片标签采用绝对定位,使之位于一个图片,按钮,div等标签上.或者给图片,按钮或div设置绝对定位,总之,是要让上传文件按钮和用户指定的按钮重合. (2)给上传图片标签设置大大小,使之和与它重叠的图片,按钮

  • js实现上传图片预览的方法

    本文实例讲述了js实现上传图片预览的方法.分享给大家供大家参考.具体实现方法如下: 复制代码 代码如下: function PreviewImage(imgFile) {     var filextension=imgFile.value.substring(imgFile.value.lastIndexOf("."),imgFile.value.length);     filextension=filextension.toLowerCase();     if ((filext

随机推荐