JQuery图片上传

一般上传的方式

Form表单 (enctype ="multipart/form-data")

<form id= "uploadForm" action= "#" method= "post" enctype ="multipart/form-data">  
     <p >上传文件: <input type ="file" name="file" /></p>  
     <input type ="submit" value="上传"/>  
</form>

JQuery代码

$.ajax({  
     url : "#",  
     type : "POST",  
     data : $( '#uploadForm').serialize(),    //表单序列化 ,【注意】上传文件的文件流是无法被序列化并传递的
     processData:false,   //  告诉jquery不要处理发送的数据
     contentType:false    // 告诉jquery不要设置content-Type请求头     
     success : function(data) {  

     }
});

关于FormData 的方式上传

与普通的Ajax相比,它能异步上传二进制文件
第一种方式

var oMyForm = new FormData();                    // 创建一个空的FormData对象
oMyForm.append("userName","Coco");          // append()方法添加字段
oMyForm.append("accountNum",123456);     // 数字123456立即被转换成字符串“123456”
oMyForm.append("userFile",fileInputElement.files[0]);

第二种方式

var FormElement = $("#myFormElement");

$.ajax({  
     url : "#",  
     type : "POST",  
     data:new FormData(FormData),
     processData:false,   //  告诉jquery不要处理发送的数据
     contentType:false    // 告诉jquery不要设置content-Type请求头
     success : function(data) {  

     }
});

第三种方式

利用form对象的getFormData方法生成
var formobj = document.getElementById("myFormElement");
var formdata = formobj.getFormData();

完整的例子

<p><input type="file" id="upfile"></p>
<p><input type="button" id="upJS" value="用原生JS上传"></p>
<p><input type="button" id="upJQuery" value="用jQuery上传"></p>


<script>
                /*原生JS版*/
                document.getElementById("upJS").onclick = function() {
                    /* FormData 是表单数据类 */
                    var fd = new FormData();
                    var ajax = new XMLHttpRequest();
                    fd.append("upload", 1);
                    /* 把文件添加到表单里 */
                    fd.append("upfile", document.getElementById("upfile").files[0]);
                    ajax.open("post", "{php echo $this->createWebUrl('bisai',array('op'=>'uploadPDF'));}", true);

                    ajax.onload = function () {
                        console.log(ajax.responseText);
                    };

                    ajax.send(fd);

                }

                /* jQuery 版 */
                $('#upJQuery').on('click', function() {
                    var fd = new FormData();
                    fd.append("upload", 1);
                    fd.append("upfile", $("#upfile").get(0).files[0]);
                    $.ajax({
                        url: "{php echo $this->createWebUrl('bisai',array('op'=>'uploadPDF'));}",
                        type: "POST",
                        processData: false,
                        contentType: false,
                        data: fd,
                        success: function(d) {
                            console.log(d);
                        }
                    });
                });
</script>

附关于图片的格式转换

  1. canvas转换为dataURL (从canvas获取dataURL)
var dataurl = canvas.toDataURL('image/png');
var dataurl2 = canvas.toDataURL('image/jpeg', 0.8);
  1. File对象转换为dataURL、Blob对象转换为dataURL

File对象也是一个Blob对象,二者的处理相同。

function readBlobAsDataURL(blob, callback) {
    var a = new FileReader();
    a.onload = function(e) {callback(e.target.result);};
    a.readAsDataURL(blob);
}
//example:
readBlobAsDataURL(blob, function (dataurl){
    console.log(dataurl);
});
readBlobAsDataURL(file, function (dataurl){
    console.log(dataurl);
});
  1. dataURL转换为Blob对象、dataURL转换为File对象

File继承于Blob,扩展了一些属性(文件名、修改时间、路径等)。绝大多数场景下,使用Blob对象就可以了。
兼容性:Edge浏览器不支持File对象构造函数,也就是Edge里不能new File()。

function dataURLtoBlob(dataurl) {
    var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
        bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
    while(n--){
        u8arr[n] = bstr.charCodeAt(n);
    }
    return new Blob([u8arr], {type:mime});
}
function dataURLtoFile(dataurl, filename) {
    var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
        bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
    while(n--){
        u8arr[n] = bstr.charCodeAt(n);
    }
    return new File([u8arr], filename, {type:mime});
}
//test:
var blob = dataURLtoBlob('data:text/plain;base64,YWFhYWFhYQ==');
var file = dataURLtoFile('data:text/plain;base64,YWFhYWFhYQ==', 'test.txt');
  1. dataURL图片数据绘制到canvas

先构造Image对象,src为dataURL,图片onload之后绘制到canvas

var img = new Image();
img.onload = function(){
    canvas.drawImage(img);
};
img.src = dataurl;
  1. File,Blob的图片文件数据绘制到canvas

还是先转换成一个url,然后构造Image对象,src为dataURL,图片onload之后绘制到canvas
利用上面的 readBlobAsDataURL 函数,由File,Blob对象得到dataURL格式的url,再参考 dataURL图片数据绘制到canvas
不同的方法用于构造不同类型的url (分别是 dataURL, objectURL(blobURL), filesystemURL)。这里不一一介绍,仅以dataURL为例。
filesystemURL不是指本地文件URL的形式(file:///….), 而是格式类似于 filesystem:http://... 的一种URL,支持沙盒文件系统的浏览器支持(目前仅Chrome)支持。

readBlobAsDataURL(file, function (dataurl){
    var img = new Image();
    img.onload = function(){
        canvas.drawImage(img);
    };
    img.src = dataurl;
});
  1. Canvas转换为Blob对象并使用Ajax发送

转换为Blob对象后,可以使用Ajax上传图像文件。
先从canvas获取dataurl, 再将dataurl转换为Blob对象

var dataurl = canvas.toDataURL('image/png');
var blob = dataURLtoBlob(dataurl);
//使用ajax发送
var fd = new FormData();
fd.append("image", blob, "image.png");
var xhr = new XMLHttpRequest();
xhr.open('POST', '/server', true);
xhr.send(fd);

微信上传的例子

HTML

           <div class="weui_cell">
                    <div class="weui_cell_bd weui_cell_primary">
                        <div class="weui_uploader">
                            <div class="weui_uploader_hd weui_cell">
                                <div class="weui_cell_bd weui_cell_primary">身份证正面</div>
                                <div class="weui_cell_ft js_counter" id="js_counter_cardz">
                                    {empty name="user.cardf"}
                                    0/1
                                    {else /}
                                    1/1
                                    {/empty}
                                </div>
                            </div>
                            <div class="weui_uploader_bd">
                                <ul class="weui_uploader_files" id="cardz">
                                    <!-- 预览图插入到这 -->
                                    {notempty name="user.cardz"}
                                    <li class="weui_uploader_file cardz"
                                        style="background-image:url('{$user.cardz}')"></li>
                                    {/notempty}
                                </ul>
                                <div class="weui_uploader_input_wrp">
                                    <input class="weui_uploader_input js_file_cardz" data_type="cardz" type="file" accept="image/jpg,image/jpeg,image/png,image/gif" multiple=""></div>
                            </div>
                        </div>
                    </div>
                </div>
 <div class="weui_cell">
                    <div class="weui_cell_bd weui_cell_primary">
                        <div class="weui_uploader">
                            <div class="weui_uploader_hd weui_cell">
                                <div class="weui_cell_bd weui_cell_primary">身份证反面</div>
                                <div class="weui_cell_ft js_counter " id="js_counter_cardf">
                                    {empty name="user.cardf"}
                                    0/1
                                    {else /}
                                    1/1
                                    {/empty}
                                </div>
                            </div>
                            <div class="weui_uploader_bd">
                                <ul class="weui_uploader_files" id="cardf">
                                    <!-- 预览图插入到这 -->
                                    {notempty name="user.cardf"}
                                    <li class="weui_uploader_file cardf"
                                        style="background-image:url('{$user.cardf}')"></li>
                                    {/notempty}
                                </ul>
                                <div class="weui_uploader_input_wrp">
                                    <input class="weui_uploader_input js_file_cardf" data_type="cardf" type="file" accept="image/jpg,image/jpeg,image/png,image/gif" multiple=""></div>
                            </div>
                        </div>
                    </div>
                </div>

JS

<script>
    $(".base_info").click(function (){

        var data = $("#base_info").serialize();
        $.ajax({
            url:"{:url('mobile/base_submit')}"+"?token={$token}&id={$id}&is_mobile=1",
            type:"post",
            dataType:"json",
            data:data,
            success:function( response ){
                if( response.code == 200 ){
                    alert(response.msg);
                    window.history.go(-1);
                }else{
                    alert(response.msg);
                }
            }
        });
    })

    //DataUrl转Blob
    function dataURLtoBlob(dataurl) {
        var arr = dataurl.split(','), mime = arr[0].match(/:(.*?);/)[1],
            bstr = atob(arr[1]), n = bstr.length, u8arr = new Uint8Array(n);
        while(n--){
            u8arr[n] = bstr.charCodeAt(n);
        }
        return new Blob([u8arr], {type:mime});
    }
</script>
<script>
    $.weui = {};
    $.weui.alert = function(options) {
        options = $.extend({
            title: '警告',
            text: '警告内容'
        }, options);
        var $alert = $('.weui_dialog_alert');
        $alert.find('.weui_dialog_title').text(options.title);
        $alert.find('.weui_dialog_bd').text(options.text);
        $alert.on('touchend click', '.weui_btn_dialog', function() {
            $alert.hide();
        });
        $alert.show();
    };

    $(function() {
        // 允许上传的图片类型
        var allowTypes = ['image/jpg', 'image/jpeg', 'image/png', 'image/gif'];
        // 1024KB,也就是 1MB
        var maxSize = 1024 * 1024;
        // 图片最大宽度
        var maxWidth = 300;
        // 最大上传图片数量
        var maxCount = 1;
        $('.js_file_cardz').on('change', function(event) {
            var type = $(this).attr("data_type");
            upload(event,type);
        });

        $('.js_file_cardf').on('change', function(event) {
            var type = $(this).attr("data_type");
            upload(event,type);
        });

        function upload(event,type)
        {
            var files = event.target.files;

            // 如果没有选中文件,直接返回
            if (files.length === 0) {
                return;
            }

            for (var i = 0, len = files.length; i < len; i++) {
                var file = files[i];
                var reader = new FileReader();

                // 如果类型不在允许的类型范围内
                if (allowTypes.indexOf(file.type) === -1) {
                    $.weui.alert({
                        text: '该类型不允许上传'
                    });
                    continue;
                }

                if (file.size > maxSize) {
                    $.weui.alert({
                        text: '图片太大,不允许上传'
                    });
                    continue;
                }

                if ($('.'+type).length >= maxCount) {
                    $.weui.alert({
                        text: '最多只能上传' + maxCount + '张图片'
                    });
                    return;
                }

                reader.onload = function(e) {
                    var img = new Image();
                    img.onload = function() {
                        // 不要超出最大宽度
                        var w = Math.min(maxWidth, img.width);
                        // 高度按比例计算
                        var h = img.height * (w / img.width);
                        var canvas = document.createElement('canvas');
                        var ctx = canvas.getContext('2d');
                        // 设置 canvas 的宽度和高度
                        canvas.width = w;
                        canvas.height = h;
                        ctx.drawImage(img, 0, 0, w, h);
                        var base64 = canvas.toDataURL('image/png');

                        //删除之前的照片
                        $('#'+type).empty();

                        // 插入到预览区
                        var $preview = $('<li class="weui_uploader_file weui_uploader_status '+type+'" style="background-image:url(' + base64 + ')"><div class="weui_uploader_status_content">0%</div></li>');
                        $('#'+type).append($preview);
                        var num = $('#'+type).length;
                        $('#js_counter_'+type).text(num + '/' + maxCount);

                        //上传
                        var file_data = dataURLtoBlob(base64);
                        var formData = new FormData();
                        formData.append("user_id", "{$user.id}");
                        formData.append("type", type);
                        formData.append("file_data", file_data);


                        $.ajax({
                            url:"{:url('api/common/imageUploadCard')}",
                            type:"post",
                            data:formData,
                            processData: false,
                            contentType:false,
                            cache:false,
                            success:function( response ){
                                if( response.code == 200 ){
                                    $preview.find('.weui_uploader_status_content').text('100%');
                                    $.weui.alert({text: response.msg,title:'提示'});
                                }else{
                                    $preview.removeClass('weui_uploader_status').find('.weui_uploader_status_content').remove();
                                    $.weui.alert({text: response.msg});
                                }
                            }
                        });
                    };

                    img.src = e.target.result;
                };
                reader.readAsDataURL(file);
            }
        }
    });
</script>

相关问题

[jQuery的ajax报错Illegal invocation,一般会是什么原因引起的?]

可能是傳出去的 data 格式有問題
或者試試看 processData: false 設定為 false,

我是參考 https://stackoverflow.com/que...

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容