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...

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 215,294评论 6 497
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,780评论 3 391
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,001评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,593评论 1 289
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,687评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,679评论 1 294
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,667评论 3 415
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,426评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,872评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,180评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,346评论 1 345
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,019评论 5 340
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,658评论 3 323
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,268评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,495评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,275评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,207评论 2 352

推荐阅读更多精彩内容