自己实现AJAX异步上传文件

在项目中经常用到文件上传,然后就找各种各样的插件。但用着用着总不是很多地方不是很称手,需要修修改改。所以今天干脆自己写个吧。

先说说具体需求:

  1. 上传文件做到所见所得,就是选择文件之后能立马看到
  2. 可以方便用在用js异步提交的表单中

HTML页面部分是这样子

<div>
    <!-- 图片./images/add_img.png就是一个很大的加号 +  -->
    <img style="cursor: pointer;" src="./images/add_img.png" alt="点击上传" width="100" title="点击上传" class="upload-img" data-id="img">
    <input type="hidden" name="image" value="" class="upload-img-input" data-id="img">
    <input style="display: none" type="file" accept="image/gif,image/jpeg,image/jpg,image/png,image/bmp" name="file" id="file_img" data-id="img" onchange="upload_image(this);">
</div>

在input:file的accept属性中定义可以上传的文件格式(MIME 类型)在这里我们列出常用的图片类型:image/gif,image/jpeg,image/jpg,image/png,image/bmp

其实在这大家会说后缀是.jpg.jpeg的图片的mime type不都是image/jpeg吗?为什么还要加个image/jpg?

没错,是这样如果你只写image/jpeg用谷歌浏览器是没问题的。但是在微信浏览器,QQ浏览器中就不行了,后来找不到问题,尝试了好多次才发现这个问题。没办法,国产浏览器不按标准造的原因 ╮(╯▽╰)╭

其他文件格式大家看这里 w3school

重点是js:

//点击图片的时候 触发隐藏的input:file的点击事件
$(".upload-img").click(function(){
    var id = $(this).data('id');
    var file = document.getElementById('file_' + id);
    file.click();
});
function upload_image(pic_file) {
    var id = $(pic_file).data('id');
    var input = $("input.upload-img-input[data-id="+id+"]");    //找到相应的隐藏域
    var pic = $("img.upload-img[data-id="+id+"]");              //找到相应的预览图片

    var file = pic_file.files[0];
    if (file.size > 2 * 1024 * 1024) {   //设置限制文件大小 不大于2MB
        alert('上传文件不能大于2M!');
        return false;
    }

    var fd = new FormData();    //使用formData对象
    fd.append("pic_file", file);
    //fd.append("name", name);  //可以添加其他字段,比如有些框为了安全加的csrf_token

    var xhr = new XMLHttpRequest();

    xhr.open("POST", 'upload_file.php');    //这里是后端处理的地址
    xhr.onload = function () {
        if (xhr.status == 200) {
            var obj = eval('(' + xhr.responseText + ')');   //把json字符串转换成js对象
            if (obj.ret == 200) {   //上传成功
                var pic_url = obj.data.url; //显示预览图
                input.val(pic_url);         //把地址放到隐藏域
                pic.attr('src', pic_url);
            } else {
                alert(obj.msg);
            }
        } else {
            alert('上传失败,请稍候再试');
        }
    };
    xhr.send(fd);
}

我们服务端上传返回的json格式是这样

{
    "ret": 200,
    "msg": "ok",
    "data": {
        "url": "你的图片url地址"
    }
}

评论