upload.js 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  1. /**
  2. * 上传文件处理,验证文件类型和大小 验证通过返回数据
  3. * {
  4. * errCode : 0为通过,1为类型错误,2为大小超出,
  5. * url : base64位的文件数据
  6. * }
  7. * @author lautin
  8. * @created 2019-11-22 17:20:32
  9. */
  10. // 将buffer转化成utf-8格式
  11. function iconvToUtf8(bufferArr, encoding) {
  12. let x = new Uint8Array(bufferArr);
  13. let ret = new TextDecoder(encoding).decode(x);
  14. return ret;
  15. }
  16. class Upload {
  17. constructor(conf) {
  18. // 获取文件DOM对象
  19. if (!conf.ele.nodeType) conf.ele = document.querySelector(conf.ele);
  20. // 将配置信息写入实例对象中
  21. Object.assign(this, {
  22. file: conf.ele.files[0], // 文件对象
  23. name: conf.ele.files[0].name, // 文件名称
  24. error: '', // 错误代号
  25. data: '', // 存储数据
  26. // 类型检测
  27. isIMG: null,
  28. isTXT: null,
  29. }, conf);
  30. }
  31. checkType() {
  32. // 验证文件类型,allowType需要设置['images/jpg', 'image/png'...]
  33. if (this.allowType) {
  34. if (!this.allowType.includes(this.file.type)) {
  35. this.error = `${this.file.type}类型文件不合法`;
  36. this.errno = 101;
  37. }
  38. }
  39. this.isIMG = this.file.type.startsWith("image");
  40. this.isTXT = this.file.type.startsWith("text");
  41. }
  42. checkSize() {
  43. // 验证文件类型,allowSize传入的值以M为单位
  44. if (this.allowSize) {
  45. const maxByte = this.allowSize * 1024 * 1024;
  46. if (this.file.size > maxByte) {
  47. this.error = `文件大小不能超出${this.allowSize}M`;
  48. this.errno = 102;
  49. }
  50. }
  51. }
  52. readFile() {
  53. return new Promise((resolve, reject) => {
  54. const fr = new FileReader;
  55. fr.onloadend = function () {
  56. // 如果为文本 返回文件内容
  57. let data;
  58. switch (true) {
  59. case this.isIMG :
  60. data = fr.result;
  61. break;
  62. case this.isTXT :
  63. data = iconvToUtf8(fr.result, "gbk");
  64. break;
  65. default :
  66. data = null;
  67. break;
  68. }
  69. resolve(data);
  70. }.bind(this);
  71. fr.onabort = function () {
  72. // 上传意外被中断
  73. reject(new Error(103));
  74. }
  75. fr.onerror = function () {
  76. // 上传过程发生错误
  77. reject(new Error(104));
  78. }
  79. // 如果是图片的话 则返回base64 URL格式数据 否则返回ArrayBuffer
  80. this.isIMG ? fr.readAsDataURL(this.file) : fr.readAsArrayBuffer(this.file);
  81. });
  82. }
  83. static async start(settings) {
  84. // 创建实例
  85. const ins = new Upload(settings);
  86. // 验证类型
  87. ins.checkType();
  88. // 验证大小
  89. ins.checkSize();
  90. console.log(ins.errno);
  91. // 验证不通过 则直接触发reject
  92. console.log()
  93. if (ins.error) throw new Error(ins.errno);
  94. else {
  95. // 读取文件的操作 发生错误会进入catch 成功则返回data数据
  96. ins.data = await ins.readFile();
  97. return ins;
  98. }
  99. }
  100. }
  101. export default Upload.start;