js移动端多图上传预览传给后端

前端开发-阿锋      2022-02-14     434

关键词:

HTML5定义了 FileReader 作为文件 API 的重要成员用于读取文件,根据 W3C 的定义,FileReader接口提供了读取文件的方法和包含读取结果的事件模型。

FileReader的实例拥有 4 个方法,其中 3 个用以读取文件,另一个用来中断读取。下面的表格列出了这些方法以及他们的参数和功能,需要注意的是 ,无论读取成功或失败,方法并不会返回读取结果,这一结果存储在 result 属性中。

方法名参数描述
abort none 中断读取
readAsBinaryString file 将文件读取为二进制码
readAsDataURL file 将文件读取为 DataURL
readAsText file, [encoding] 将文件读取为文本

readAsText:该方法有两个参数,其中第二个参数是文本的编码方式,默认值为 UTF-8。这个方法非常容易理解,将文件以文本方式读取,读取的结果即是这个文本文件中的内容。
readAsBinaryString:该方法将文件读取为二进制字符串,通常我们将它传送到后端,后端可以通过这段字符串存储文件。
readAsDataURL:这是例子程序中用到的方法,该方法将文件读取为一段以 data: 开头的字符串,这段字符串的实质就是 Data URL,Data URL是一种将小文件直接嵌入文档的方案。这里的小文件通常是指图像与 html 等格式的文件。

FileReader还包含了一套完整的事件模型,用于捕获读取文件时的状态,下面这个表格归纳了这些事件。

事件描述
onabort 中断时触发
onerror 出错时触发
onload 文件读取成功完成时触发
onloadend 读取完成触发,无论成功或失败
onloadstart 读取开始时触发
onprogress 读取中

文件一旦开始读取,无论成功或失败,实例的 result 属性都会被填充。如果读取失败,则 result 的值为 null ,否则即是读取的结果,绝大多数的程序都会在成功读取文件的时候,抓取这个值。

了解了H5提供的 FileReader 后,我们就使用 FileReader 来实现同事选择多张图片并上传。

首先,在 HTML 加入一个file表单,并设置其为 multiple(浏览器在对multiple、disabled、checked、selected等这类属性进行解析时,只要这些属性存在,默认的就会被解析成true,甭管你设置的是disabled=true或者disabled=false亦或是disabled="",如果不想这些属性起作用,唯有用js来remove掉这些属性,除非你不设置这些属性。),并设置accept="image/*"用以只能选择图片类型的文件,代码如下:

<input type="file"  accept="image/*" name="upload" id="upload" multiple>
<input type="hidden" id="hiddenImgUrl" />   <!--设置这个隐藏域是为了便于存放上传至服务器后返回的图片地址-->
//图片上传
var file = {
    upload: function (e) {
        var self = this;
        var files = e.target.files;
        var type = files[0].type.split(/)[0];
        if (type != image) {
            alertMsg(请上传图片);
            return;
        }
        //var size = Math.floor(file.size / 1024 / 1024);
        //if (size > 3) {
        //    alert(‘图片大小不得超过3M‘);
        //    return;
        //};
        for (var i = 0; i < files.length; i++) {
            var reader = new FileReader();
            reader.readAsDataURL(files[i]);
            reader.onloadstart = function () {
                //用以在上传前加入一些事件或效果,如载入中...的动画效果
            };
            reader.onloadend = function (e) {
                var dataURL = this.result;
                var imaged = new Image();
                imaged.src = dataURL;
                imaged.onload = function () {   //利用canvas对图片进行压缩
                    var canvas = document.createElement(canvas);
                    var ctx = canvas.getContext(2d);
                    var w = 0;
                    var h = 0;
                    if (this.width > this.height) {
                        h = 1000;
                        var scale = this.width / this.height;
                        h = h > this.height ? this.height : h;
                        w = h * scale;
                    }
                    else {
                        w = 1000;
                        var scale = this.width / this.height;
                        w = w > this.width ? this.width : w
                        h = w / scale;

                    }


                    var anw = document.createAttribute("width");
                    var anh = document.createAttribute("height");
                    if (this.width > this.height) {
                        anw.value = h;
                        anh.value = w;
                    }
                    else {
                        anw.value = w;
                        anh.value = h;
                    }
                    canvas.setAttributeNode(anw);
                    canvas.setAttributeNode(anh);

                    if (this.width > this.height) {
                        ctx.translate(h, 0);
                        ctx.rotate(90 * Math.PI / 180)
                        ctx.drawImage(this, 0, 0, w, h);
                        ctx.restore();
                    }
                    else {
                        ctx.drawImage(this, 0, 0, w, h);
                    }
                    dataURL = canvas.toDataURL(image/jpeg);

                    //回调函数用以向数据库提交数据
                    self.callback(dataURL);
                };
            };
        }
    },
    event: function () {
        $("#upload").change(function (e) {           
            file.upload(e);
        });
    },
    callback: function (dataURL) {
        $.ajaxSettings.async = false;   //这里必须将ajax的异步改为同步才可以把返回并保存在隐藏域中的图片地址取出同时加在地址栏中作为参数一并传入下一个页面,这样做的目的是因为返回的图片地址不是一个json数组,而是单个的json字符串,所以只能将返回的图片地址json字符串拼接在一起作为参数传到下一个页面
        $.post(url, dataURL, function (res) {   //将base64图片流的图片通过后台转换成普通的图片路径并上传至服务器
            var imgUrl = $("#hiddenImgUrl").val();
            if (res.success) {
                $(".loading").hide();
                if (imgUrl != "") {
                    $("#hiddenImgUrl").val(imgUrl + "|" + res.imgUrl);   //中间加一个 | 是为了到下一个页面便于将传过去的图片地址参数转换为数组
                } else {
                    $("#hiddenImgUrl").val(res.imgUrl);
                }

                var imgUrl = $("#hiddenImgUrl").val();
                window.location.href = "apply.html?imgUrl=" + imgUrl;
                        
            } else {
                alert(res.message);
            }
        }, "json");
    },
   init: function () {
        this.event();
    }
}
file.init();

 

由于在通过post向服务器上传时采用了同步的方式,所以我在写项目的过程中,老是无法实现加载中的动画效果,并且把加载中的动画效果放在 reader.onloadstart方法中依旧不起作用,最后只能放在了$("#upload").change(function (e) {})方法中,代码如下:

 event: function () {
        $("#upload").change(function (e) {
            $(".loading").show();          
            file.upload(e);
        });
    }

以上是同时上传多张图片并将图片传入下一个页面继续进行后续操作,那么如何在同时上传完多张图片后在本页再预览这些图片呢?其实方法也是很简单的,上边callback函数里边的$.post的返回值里就包含了上传至服务器后的图片路径,将这些路径赋给img标签的src,然后再插入到页面中就OK了,代码如下:

callback: function (dataURL) {        
        $.post(url, dataURL, function (res) {   //将base64图片流的图片通过后台转换成普通的图片路径并上传至服务器
            if (res.success) {
                $(".loading").hide();
                var result = <div class="result"><img src="+res.imgUrl+" /></div>;
                var div = document.createElement(div);
                div.innerHTML = result;
                document.body.appendChild(div);               
            } else {
                alert(res.message);
            }
        }, "json");
    }

以上在预览图片时由于不需要跳转,不需要传入返回的所有图片的路径作为参数,所以也就不需要将ajax的异步设置为同步了。

 



移动端js实现图片上传预览

方法一:<htmlxmlns="http://www.w3.org/1999/xhtml"><head><metahttp-equiv="Content-Type"content="text/html;charset=utf-8"/><title>测试页面</title><scripttype="text/javascript"&g 查看详情

js前端实现多图图片上传预览

<htmlxmlns="http://www.w3.org/1999/xhtml"><head><metahttp-equiv="Content-Type"content="text/html;charset=utf-8"/><title>测试页面</title><scripttype="text/javascript">// 查看详情

使用input的file进行上传进行预览(代码片段)

在使用file上传文件的时候,想到了图片预览的功能,然后查询了一些资料,一种是需要后端配合,将数据变成base64或者buff等数据传给后端然后调取接口进行显示,但是这种需要后端的配合和网络请求,感觉不如在纯前端操作方... 查看详情

jquery图片上传前先在本地预览(不经过后端处理)

前段时间遇到一个问题,前端想实现图片上传预览(不经过后端PHP或JAVA处理),用户点击file按钮上传文件,点击确定马上就能看到预览的效果,但在实现的时候无论怎样都取不到file上图片的真实路径,得到的反而是C:fakepatha.jpg... 查看详情

移动端图片上传预览

前天要做wap版的图片上传预览,找了好半天才找到比较适合的插件,我在该插件的基础上修改了一些东西,比如:上传后的图片删除后不能再添加、不能限制上传图片的数量。input虽然有multiple(多选),但是android目前是不支持... 查看详情

移动端h5实现拍照上传图片并预览

.移动端实现图片上传并预览,用到h5的input的file属性及filereader对象;经测除了android上不支持多图片上传,其他基本ok实用;一:先说一下单张图片上传(先上代码):html结构(含多张图片容器div):1<divclass="fileBtn">2<p>点... 查看详情

移动端上传照片

...件,在这里我要感谢作者,虽然不知道是谁。应用场景:移动端管调用手机相册和相机,上传图片给接口进行识别插件下载百度云地址:链接:https:// 查看详情

layui+django实现多图上传预览删除解决csrf验证及上传端口异常

最近碰到一个项目需要多图上传且能预览能删除前端使用layui引入脚本<link rel="stylesheet" href="/static/layui/css/layui.css"><script src="/static/layui/layui.js"></script><script src="/static/js/jquery-1.8.2.min.js"></script>... 查看详情

html5多图上传预览

<p><label>请选择一个文件:</label><inputtype="file"id="file"multiple="multiple"onchange="readAsDataURL()"/></p><divid="result"name="result"></div>  <script>  va 查看详情

移动端预览(双指缩放移动)富文本编辑器上传的图片(代码片段)

通过使用vue-photo-preview插件,实现移动端图片的预览,全屏等功能。1.安装插件npminstallvue-photo-preview--save2.main引入importpreviewfrom'vue-photo-preview'import'vue-photo-preview/dist/skin.css'Vue.use 查看详情

一键多图预览

】一键多图预览【英文标题】:Multipleimageinonebuttonwithpreview【发布时间】:2017-09-1710:09:49【问题描述】:图片上传预览有点问题。这是元素的预览:这是代码:<divclass="img-container"><imgid="preview-1"src=""/><divclass="more"><... 查看详情

uniapp上传图片至服务器,获得在线图片链接预览(实战)

...,写一个成功的回调函数,在回到函数里面添加一个图片上传的方法uploadFile,在方法里面添加url,等参数。若是请求成功则返回一个图片链接添加接口之后的,demo如下: 查看详情

在 Sails.js 后端项目中访问上传的图像

】在Sails.js后端项目中访问上传的图像【英文标题】:AccessuploadedimageinSails.jsbackendproject【发布时间】:2015-09-2000:41:12【问题描述】:我正在尝试上传,然后访问图像。上传进展顺利,将图像上传到资产/图像,但是当我尝试从浏... 查看详情

前端获取图片压缩后上传给后台

   此前有同事跟我聊过关于移动端用canvas压缩图片后再上传的功能,最近有了点空闲时间,所以就实践了一下。demo效果链接在文章底部贴出。  在做移动端图片上传的时候,用户传的都是手机本地图片,而本地图片... 查看详情

前端获取图片压缩后上传给后台

   此前有同事跟我聊过关于移动端用canvas压缩图片后再上传的功能,最近有了点空闲时间,所以就实践了一下。demo效果链接在文章底部贴出。  在做移动端图片上传的时候,用户传的都是手机本地图片,而本地图片... 查看详情

后端图片上传

用到的是simpleUpload.js需要依赖jquery.js、layer.js <div> <divclass="input-inline"> <inputtype="text"value=""class="inputinput-auto"id="pic"name="pic"size="25"> <inputtype="text"val 查看详情

iframe渲染后端二进制流实现pdf等预览

参考技术Atemplate部分:js方法: 查看详情

picker-extend移动端级联选择插件

...h1align="center">picker-extend.js</h1>一款多功能的移动端滚动选择器,支持单选到多选、支持多级级联、提供自定义回调函数、提供update函数二次渲染、重定位函数、兼容pc端拖拽等等..picker-extend移动端级联选择插件()p... 查看详情