最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • 封装一个uploader组件(纯Javascript版本)

    正文概述 掘金(追公交车的小仙女)   2021-01-03   489

    一些要提前学习的知识:

    • input 使用 type=file 实现文件上传
    • transform: translateX()实现加载进度条动画;
    • 原生 XMLHttpRequest 请求的封装;
    • 使用 FormData
    • 后端使用 node.js 完成上传接口。

    input

    • input 使用 type=file 实现文件上传
    • accept 属性可以规定文件上传的文件类型,可以接收的参数有:
    描述
    audio/*接收所有的声音文件video/*接收所有的视频文件image/*接收所有的图片文件image/png,image/jpeg接收 png,jpe,jpg,jpeg 图片文件

    更多 MIME 类型列表:https://www.w3school.com.cn/media/media_mimeref.asp

    Live Server

    VSCode 中使用 live-server 插件,live-server是可以运行前端静态文件的一个服务器。可以实时更新我们修改的 html 文件。

    XMLHttpRequest 封装

    使用 Promise 对 xhr 请求进行了封装:在 onload 事件中对返回码不正确的情况进行了处理;onerror 事件中捕获异常。

    • Ajax = Asynchronous Javascript and XML (异步的 Javascript 和 XML);AJAX 在不重新加载整个页面的情况下,实现与服务器交换数据并更新部分网页的方法。
    • xhr.open(method,url,async); 第三个参数 true(异步),表示请求是 AJAX的,即JavaScript 无需等待服务器的响应,而是在等待服务器响应时执行其他脚本,当响应就绪后对响应进行处理。
    • 上传的 process 事件属于 XMLHttpRequest.upload 对象。
    • 下载的 process 事件属于 XMLHttpRequest 对象。
    function postFile(url, data) {
        return new Promise((resolve, reject) => {
            const xhr = new XMLHttpRequest();
            xhr.onload = function () {
                //将错误码返回
                if(xhr.status<200||xhr.status>=300){
                    reject(xhr.status);
                }
                resolve(xhr.response);
            }
            //获取异常
            xhr.onerror = function (e) {
                reject(e);
            }
            if (xhr.upload) {
                xhr.upload.onprogress = function progress(e) {
                    if (e.total > 0) {
                        const percent = (e.loaded / e.total) * 100;
                        e.percent = percent;
                        console.log("percent: " + percent)
                    }
                };
            }
    
            xhr.open('POST', url, true);
            //xhr.setRequestHeader('Content-Type', 'application/json');
            xhr.send(data);
        })
    }
    

    补充:

    • xhr.setRequestHeader(); 可以用来设置请求头信息;位置要在 xhr.open() 之后设置才可以。
    • 因为文件上传用到了 FormData 对象,不需要重复设置请求头的 Content-Type 信息。

    Content-Type

    Content-Type 可以通过 xhr.setRequestHeader('Content-Type', 'application/json'); 在请求头中定义请求数据的类型格式。服务端也可以通过设置响应头的 Content-Type 来告诉浏览器响应数据的格式。 常用的 Content-Type 取值有:

    描述
    application/jsonJSON数据格式application/x-www-form-urlencoded中默认的encType,form表单数据被编码为key/value格式发送到服务器(表单默认的提交数据的格式)multipart/form-data需要在表单中进行文件上传时,就需要使用该格式

    更多:https://www.runoob.com/http/http-content-type.html

    另外原生的 form 表单可以通过设置 enctype 属性来设置请求数据的格式,但是我们现在一般都不用原生 form 表单向后端发送请求了。form 表单向后端发送请求存在页面刷新的问题,现在的做法只是用 form 表单展现数据而已。

    form 的使用方式:<form enctype="value">

    描述
    application/x-www-form-urlencoded在发送前编码所有字符(默认)multipart/form-data不对字符编码。在使用包含文件上传控件的表单时,必须使用该值。text/plain空格转换为 "+" 加号,但不对特殊字符编码。

    FormData

    FormData 类型是在XMLHttpRequest 2级定义的,常用的用法有两个:一个是将 form 表单的数据进行序列化,通过 AJAX 发送数据;另一个创建 Content-Type 是 multipart/form-data 类型的数据,常用于文件上传。

    <form id="myForm" action="" method="post">
      <input type="text" name="name">名字
      <input type="password" name="psw">密码
      <input type="submit" value="提交">
    </form>
    

    我们可以使用这个表单元素作为初始化参数,来实例化一个formData对象

    // 获取页面已有的一个form表单
    var form = document.getElementById( "myForm");
    // 用表单来初始化
    var formData = new FormData(form);
    // 我们可以根据name来访问表单中的字段
    var name = formData.get( "name"); // 获取名字
    var psw = formData.get( "psw"); // 获取密码
    // 当然也可以在此基础上,添加其他数据
    formData.append( "token", "kshdfiwi3rh");
    

    node.js 部分

    初始化 npm 项目

    npm init --yes
    

    安装需要的中间件:express、multer、fs。

    cnpm install multer express fs --save
    

    express

    express 可以帮我们启动一个后端服务。本示例采用 CORS(Cross-Origin-Resource-Sharing,跨域资源共享) 解决跨域问题。

    const app = express();
    // 设置跨域访问
    app.all("*", function(request, response, next) {
      // 设置跨域的域名,* 代表允许任意域名跨域
      response.header("Access-Control-Allow-Origin", "http://127.0.0.1:5500"); 
      //设置请求头 header 可以加那些属性
      response.header('Access-Control-Allow-Headers', 'Content-Type, Content-Length, Authorization, Accept, X-Requested-With');
      //设置请求头哪些方法是合法的
      response.header(
        "Access-Control-Allow-Methods",
        "PUT,POST,GET,DELETE,OPTIONS"
      );
      response.header("Content-Type", "application/json;charset=utf-8");
      next();
    });
    

    multer

    Multer 是一个 node.js 中间件,用于处理 multipart/form-data 类型的表单数据,它主要用于上传文件。 Multer 通过设置可以限制上传的文件大小和类型:

    //文件大小 
    const limits = {
      fileSize: 1024*1024 //单位是字节
    }
    //文件类型
    const fileFilter = function (req, file, cb) {
      const acceptableMime = ["image/jpeg", "image/png", "image/jpg", "image/gif", "application/zip", "application/x-zip-compressed"];
      // 限制类型
      // null是固定写法
      if (acceptableMime.indexOf(file.mimetype) !== -1) {
        cb(null, true); // 通过上传
      } else {
        cb(null, false); // 禁止上传
        cb(new Error('文件类型错误'));
      }
    }
    const imageUploader = multer({
      fileFilter,
      limits
    }).single("file"); //文件上传预定 name 或者 字段
    

    通过 multer.diskStorage 可以设置文件存储在服务器的位置,可以直接使用相对路径;也可以借助 fs 存储到服务器的绝对路径上。

    更多使用:https://github.com/expressjs/multer/blob/master/doc/README-zh-cn.md

    fs

    将上传的文件存放在服务器的绝对路径的位置中:

    const fs = require('fs');
    const createFolder = function(folder){
      try{
        fs.accessSync(folder);
      }catch(e){
        fs.mkdirSync(folder);
      }
    };
    const uploadFolder = 'C:/upload/';
    createFolder(uploadFolder);
    

    node.js 调试

    node --inspect server.js
    

    在前端页面的 devtools 工具中会多出来 Open dedicated DevTools for Node.js,点击这个按钮可以进行调试 node.js 服务端代码。 封装一个uploader组件(纯Javascript版本)

    效果

    封装一个uploader组件(纯Javascript版本)

    源码

    github: github.com/YY88Xu/uplo…

    感谢

    如果本文有帮助到你的地方,记得点赞哦,这将是我坚持不断创作的动力~

    参考:
    www.cnblogs.com/tianyuchen/…
    www.jianshu.com/p/562cf4baf…
    blog.csdn.net/scorpio_h/a…
    www.jb51.net/article/162…
    blog.csdn.net/walk_man_3/…
    www.cnblogs.com/sexintercou…


    起源地下载网 » 封装一个uploader组件(纯Javascript版本)

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元