js的Blob以及和File、base64的转化
Blob是什么
在JavaScript中,Blob(二进制大对象)对象是一种用于表示原始数据的类文件对象,它存储了任意类型的数据,通常是二进制数据,但也可以包含文本数据或其他格式的数据。Blob对象通常用于在客户端浏览器中处理二进制数据,比如文件上传、数据传输等场景。(Blob对象可以将任意类型的数据转换为二进制形式进行存储和处理。这使得Blob对象成为处理各种数据类型的有效工具,包括文本、图像、音频、视频等。在JavaScript中,Blob对象提供了一种统一的接口来处理这些数据,无论是从用户上传的文件中获取数据,还是从其他来源获取数据,都可以使用Blob对象来进行二进制处理。)
Blob的用途
Blob对象常见的使用情况包括:
文件上传:当用户通过网页上传文件时,浏览器会创建一个Blob对象来表示上传的文件数据,然后可以将该Blob对象发送到服务器端进行处理。
数据传输:在客户端与服务器端进行数据交互时,可以使用Blob对象来存储和传输二进制数据,例如通过XMLHttpRequest或Fetch API发送Blob对象。
图像处理:在客户端对图像进行处理时,可以将图像数据存储在Blob对象中,并通过Canvas API等技术进行操作和显示。
媒体处理:在处理音频或视频等媒体数据时,可以使用Blob对象来存储和处理媒体数据。
和file文件流的关系
以下是Blob对象和File对象之间的联系和区别:
Blob对象:
Blob对象是二进制数据的容器,可以包含任意类型的数据,如文本、图像、音频或视频等。
可以通过构造函数new Blob(data, options)
创建 Blob 对象,其中data
是包含数据的数组或数组缓冲区,options
是一个可选对象,用于指定 Blob 的 MIME 类型和结束符等信息。File对象:
File对象是Blob对象的一种扩展,通常用于表示用户系统中的文件,具有文件名和最后修改日期等属性。
可以通过new File(data, name, options)
构造函数创建 File 对象,其中data
是包含数据的数组或数组缓冲区,name
是文件名,options
是一个可选对象,用于指定文件的 MIME 类型和最后修改日期等信息。
联系与区别:
File对象是Blob对象的子类,因此所有可以对Blob对象执行的操作也同样适用于File对象。
File对象在表示文件时具有额外的元数据,如文件名和最后修改日期等。
在实际使用中,Blob对象通常用于处理二进制数据,而File对象则用于处理用户系统中的文件,如文件上传和操作。
因此,可以说File对象是Blob对象的一种特殊情况,用于在JavaScript中表示用户系统中的文件,并提供了额外的文件相关的属性。
Blob和File文件流,base64的转化
Blob对象转文件: 可以使用File
构造函数将Blob对象转换为文件对象。File
构造函数接受一个Blob对象和一个文件名作为参数,然后返回一个文件对象。
- var blob = new Blob(["blob data"], { type: "text/plain" });
- var file = new File([blob], "filename.txt");
Blob对象转Base64: 可以使用FileReader
对象将Blob对象转换为Base64编码的字符串。FileReader
对象可以读取Blob对象中的数据,并以指定的编码格式输出。
- var blob = new Blob(["blob data"], { type: "text/plain" });
- var reader = new FileReader();
- reader.readAsDataURL(blob);
- reader.onload = function () {
- var base64String = reader.result;
- };
Base64转Blob对象: 可以将Base64编码的字符串转换回Blob对象。这可以通过创建一个新的Blob对象并指定Base64字符串的数据类型完成。
- var base64String = "base64 data";
- var byteCharacters = atob(base64String);
- var byteNumbers = new Array(byteCharacters.length);
- for (var i = 0; i < byteCharacters.length; i++) {
- byteNumbers[i] = byteCharacters.charCodeAt(i);
- }
- var byteArray = new Uint8Array(byteNumbers);
- var blob = new Blob([byteArray], { type: "image/jpeg" });
js格式化iso 8601格式的日期为其他格式-处理默认golang time类型格式问题
golang time类型格式默认序列化为json的时候,是iso 8601格式
比如:2023-03-09T23:43:43+08:00
ISO 8601 格式的时间表示法,常用于表示世界范围内的时间和日期。ISO 8601 格式使用连字符 "-" 分隔日期和时间部分,并以字母 "T" 分隔日期和时间部分,其中 "T" 后面跟着时间部分。在这个时间表示中,"2023-03-09" 表示日期部分,"23:43:43+08:00" 表示时间部分和时区偏移量。其中,"+08:00" 表示相对于 UTC 时间偏移了 8 个小时,也就是北京时间。
//[ISO 8601标准中的日期和时间格式解析]
//2024-07-24T15:36:00+08:00 (要使用"+08:00",UTC时间偏移了8个小时,也就是北京时间:表示东八区)
//2024-07-24T15:36:00-05:00 (而"-05:00"则表示西五区的美国东部时间)
//其中"T"用来分割日期和时间,时间后面跟着的"-07:00"表示西七区,注意"-"是连字符,不是减号
//其中"Z"为UTC时区标识
JS - ISO 8601格式时间,转换时间戳方法
- /*** ISO日期时间戳转时间对象 ***/
- const isoString = '2021-03-25T15:00:00Z';
- const date = new Date(isoString);
- /*** 时间对象转ISO日期时间戳字符串 ***/
- const date = new Date();
- const isoString = date.toISOString();
JS时区转换方法
- //UTC时区时间
- var iso8601String = "2022-01-01T12:00:00.000Z";
- var date = new Date(iso8601String);
- console.log('date', date)
- //打印转换的时间戳
- var utcStr = date.toUTCString(); //转换为UTC字符串
- var ut_localTimeString = date.toLocaleString("en-US", {timeZone: "UTC", hour12: false}); //UTC等于伦敦0时区
- var uk_localTimeString = date.toLocaleString("en-US", {timeZone: "Europe/London", hour12: false}); //欧洲-伦敦
- var us_localTimeString = date.toLocaleString("en-US", {timeZone: "America/New_York", hour12: false}); //北美-纽约
- var cn_localTimeString = date.toLocaleString("en-US", {timeZone: "Asia/Shanghai", hour12: false}); //亚洲-上海
- //console.log('utcStr', utcStr)
- console.log('ut_localTimeString(UTC)', ut_localTimeString);
- console.log('uk_localTimeString(UK)', uk_localTimeString);
- console.log('us_localTimeString(US)', us_localTimeString);
- console.log('cn_localTimeString(CN)', cn_localTimeString);
如下JS格式化时间方法
- function formatDate(dateString, format = 'yyyy-MM-dd HH:mm:ss') {
- const date = new Date(dateString);
- const year = date.getFullYear();
- const month = String(date.getMonth() + 1).padStart(2, '0');
- const day = String(date.getDate()).padStart(2, '0');
- const hour = String(date.getHours()).padStart(2, '0');
- const minute = String(date.getMinutes()).padStart(2, '0');
- const second = String(date.getSeconds()).padStart(2, '0');
- const formattedDate = format
- .replace(/yyyy/g, year)
- .replace(/MM/g, month)
- .replace(/dd/g, day)
- .replace(/HH/g, hour)
- .replace(/mm/g, minute)
- .replace(/ss/g, second);
- return formattedDate;
- }
- // 示例用法
- console.log(formatDate('2022-03-09 23:43:43')); // 输出:2022-03-09 23:43:43
- console.log(formatDate('03/09/2022', 'yyyy年MM月dd日')); // 输出:2022年03月09日
- console.log(formatDate('09 Mar 2022 23:43:43 GMT', 'yyyy-MM-dd HH:mm:ss')); // 输出:2022-03-09 23:43:43
解决JS两数相加的精度问题
JS中小数相加存在的精度问题
- console.log(0.1+0.2);//0.30000000000000004
- console.log(0.2+0.7);//0.8999999999999999
解决办法
- <script>
- // 精确乘法计算
- function FloatMul(arg1, arg2) {
- var m = 0,
- s1 = arg1.toString(),//将第一个数据转换成字符出类型
- s2 = arg2.toString();//将第二个数据转换成字符出类型
- try {
- m += s1.split(".")[1].length;//截取数据的小数部分,得到小数位数
- } catch (e) {}
- try {
- m += s2.split(".")[1].length;//截取数据的小数部分,得到小数位数
- //将两个数据的小数位数长度相加
- } catch (e) {}
- var result = (Number(s1.replace(".", "")) * Number(s2.replace(".", ""))) / Math.pow(10, m);//将两个数扩大对应的小数位数倍转换成数字类型在相乘,乘完再除于对应的扩大倍数得到最终结果
- return isNaN(result) ? 0 : result;
- }
- //获得两个小数相加的精确值
- const accountAdd = (arg1, arg2) => {
- let r1, r2, m;
- try {
- r1 = arg1.toString().split(".")[1].length;//将第一个数据转换成字符出类型,截取数据的小数部分,得到小数位数
- } catch (e) {
- r1 = 0;
- }
- try {
- r2 = arg2.toString().split(".")[1].length;//将第一个数据转换成字符出类型,截取数据的小数部分,得到小数位数
- } catch (e) {
- r2 = 0;
- }
- m = Math.pow(10, Math.max(r1, r2));//取出得到的最长位数,将10扩大最长位数倍
- return (FloatMul(arg1, m) + FloatMul(arg2, m)) / m;
- };
- let sum = accountAdd(2.3443, -1.987);
- console.log(sum);//0.3573
- </script>
解决Chrome, NET::ERR_CERT_AUTHORITY_INVALID
MD5 加密之 java 与 js 实现
MD5 加密算法实际是一种信息摘要算法,其加密不可逆向解密;
其一般用作数据签名,来确保信息传输的完整性与安全性;
- 完整性:传输数据完整未丢失
- 安全性:数据未被恶意篡改
一、java 实现 MD5 加密
- public class MD5Util {
- /**
- * 对字符串md5加密
- *
- * @param str 传入要加密的字符串
- * @return MD5加密后的字符串(小写+字母)
- */
- public static String getMD5LowerCase(String str) {
- try {
- // 生成一个MD5加密计算摘要
- MessageDigest md = MessageDigest.getInstance("MD5");
- // 计算md5函数
- md.update(str.getBytes());
- // digest()最后确定返回md5 hash值,返回值为8为字符串。因为md5 hash值是16位的hex值,实际上就是8位的字符
- // BigInteger函数则将8位的字符串转换成16位hex值,用字符串来表示;得到字符串形式的hash值
- return new BigInteger(1, md.digest()).toString(16);
- } catch (Exception e) {
- e.printStackTrace();
- return null;
- }
- }
- /**
- * 对字符串md5加密
- *
- * @param str 传入要加密的字符串
- * @return MD5加密后的字符串(大写+数字)
- */
- public static String getMD5UpperCase(String s) {
- char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
- 'A', 'B', 'C', 'D', 'E', 'F' };
- try {
- byte[] btInput = s.getBytes();
- // 获得MD5摘要算法的 MessageDigest 对象
- MessageDigest mdInst = MessageDigest.getInstance("MD5");
- // 使用指定的字节更新摘要
- mdInst.update(btInput);
- // 获得密文
- byte[] md = mdInst.digest();
- // 把密文转换成十六进制的字符串形式
- int j = md.length;
- char str[] = new char[j * 2];
- int k = 0;
- for (int i = 0; i < j; i++) {
- byte byte0 = md[i];
- str[k++] = hexDigits[byte0 >>> 4 & 0xf];
- str[k++] = hexDigits[byte0 & 0xf];
- }
- return new String(str);
- } catch (Exception e) {
- e.printStackTrace();
- return null;
- }
- }
- public static void main(String[] args) {
- String str = "\"我+Admin1234~!@#¥%……&*()\"";
- System.out.println(str);
- //"我+Admin1234~!@#¥%……&*()"
- String s1 = getMD5LowerCase(str);
- System.out.println(s1);
- //6bb6f83c026357a15cdf12e5d6b2b310
- String s2 = getMD5UpperCase(str);
- System.out.println(s2);
- //6BB6F83C026357A15CDF12E5D6B2B310
- }
- }
测试
db06c78d1e24cf708a14ce81c9b617ec
DB06C78D1E24CF708A14CE81C9B617EC
二、js 实现 MD5 加密
使用第三方库 crypto-js,示例代码如下:
- <!DOCTYPE html>
- <html lang="zh-CN">
- <head>
- <meta charset="utf-8">
- <title>111</title>
- <style type="text/css">
- body{background:#2C91AE;}
- </style>
- </head>
- <body>
- </body>
- <script src="http://172.16.102.156/public/crypto/crypto-js.min.js"></script>
- <!-- 中国文书网MD5加密封装方法调用 -->
- <script type="text/javascript" src="md5.js"></script>
- <script type="text/javascript">
- /*** 刘新修本地md5加密方法封装(大写) ***/
- // function md5(string) {
- // function rotateLeft(lValue, iShiftBits) {
- // return (lValue << iShiftBits) | (lValue >>> (32 - iShiftBits));
- // }
- // function addUnsigned(lX, lY) {
- // var lX4, lY4, lX8, lY8, lResult;
- // lX8 = (lX & 0x80000000);
- // lY8 = (lY & 0x80000000);
- // lX4 = (lX & 0x40000000);
- // lY4 = (lY & 0x40000000);
- // lResult = (lX & 0x3FFFFFFF) + (lY & 0x3FFFFFFF);
- // if (lX4 & lY4) {
- // return (lResult ^ 0x80000000 ^ lX8 ^ lY8);
- // }
- // if (lX4 | lY4) {
- // if (lResult & 0x40000000) {
- // return (lResult ^ 0xC0000000 ^ lX8 ^ lY8);
- // } else {
- // return (lResult ^ 0x40000000 ^ lX8 ^ lY8);
- // }
- // } else {
- // return (lResult ^ lX8 ^ lY8);
- // }
- // }
- // function f(x, y, z) {
- // return (x & y) | ((~x) & z);
- // }
- // function g(x, y, z) {
- // return (x & z) | (y & (~z));
- // }
- // function h(x, y, z) {
- // return (x ^ y ^ z);
- // }
- // function i(x, y, z) {
- // return (y ^ (x | (~z)));
- // }
- // function FF(a, b, c, d, x, s, ac) {
- // a = addUnsigned(a, addUnsigned(addUnsigned(f(b, c, d), x), ac));
- // return addUnsigned(rotateLeft(a, s), b);
- // }
- // function GG(a, b, c, d, x, s, ac) {
- // a = addUnsigned(a, addUnsigned(addUnsigned(g(b, c, d), x), ac));
- // return addUnsigned(rotateLeft(a, s), b);
- // }
- // function HH(a, b, c, d, x, s, ac) {
- // a = addUnsigned(a, addUnsigned(addUnsigned(h(b, c, d), x), ac));
- // return addUnsigned(rotateLeft(a, s), b);
- // }
- // function II(a, b, c, d, x, s, ac) {
- // a = addUnsigned(a, addUnsigned(addUnsigned(i(b, c, d), x), ac));
- // return addUnsigned(rotateLeft(a, s), b);
- // }
- // function convertToWordArray(string) {
- // var lWordCount;
- // var lMessageLength = string.length;
- // var lNumberOfWords_temp1 = lMessageLength + 8;
- // var lNumberOfWords_temp2 = (lNumberOfWords_temp1 - (lNumberOfWords_temp1 % 64)) / 64;
- // var lNumberOfWords = (lNumberOfWords_temp2 + 1) * 16;
- // var lWordArray = new Array(lNumberOfWords - 1);
- // var lBytePosition = 0;
- // var lByteCount = 0;
- // while (lByteCount < lMessageLength) {
- // lWordCount = (lByteCount - (lByteCount % 4)) / 4;
- // lBytePosition = (lByteCount % 4) * 8;
- // lWordArray[lWordCount] = (lWordArray[lWordCount] | (string.charCodeAt(lByteCount) << lBytePosition));
- // lByteCount++;
- // }
- // lWordCount = (lByteCount - (lByteCount % 4)) / 4;
- // lBytePosition = (lByteCount % 4) * 8;
- // lWordArray[lWordCount] = lWordArray[lWordCount] | (0x80 << lBytePosition);
- // lWordArray[lNumberOfWords - 2] = lMessageLength << 3;
- // lWordArray[lNumberOfWords - 1] = lMessageLength >>> 29;
- // return lWordArray;
- // }
- // function wordToHex(lValue) {
- // var WordToHexValue = "", WordToHexValue_temp = "", lByte, lCount;
- // for (lCount = 0; lCount <= 3; lCount++) {
- // lByte = (lValue >>> (lCount * 8)) & 255;
- // WordToHexValue_temp = "0" + lByte.toString(16);
- // WordToHexValueWordToHexValue = WordToHexValue + WordToHexValue_temp.substr(WordToHexValue_temp.length - 2, 2);
- // }
- // return WordToHexValue;
- // }
- // function utf8Encode(string) {
- // stringstring = string.replace(/\r\n/g, "\n");
- // var utftext = "";
- // for (var n = 0; n < string.length; n++) {
- // var c = string.charCodeAt(n);
- // if (c < 128) {
- // utftext += String.fromCharCode(c);
- // }
- // else if ((c > 127) && (c < 2048)) {
- // utftext += String.fromCharCode((c >> 6) | 192);
- // utftext += String.fromCharCode((c & 63) | 128);
- // }
- // else {
- // utftext += String.fromCharCode((c >> 12) | 224);
- // utftext += String.fromCharCode(((c >> 6) & 63) | 128);
- // utftext += String.fromCharCode((c & 63) | 128);
- // }
- // }
- // return utftext;
- // }
- // var x = [],
- // k, AA, BB, CC, DD, a, b, c, d,
- // S11 = 7, S12 = 12, S13 = 17, S14 = 22,
- // S21 = 5, S22 = 9 , S23 = 14, S24 = 20,
- // S31 = 4, S32 = 11, S33 = 16, S34 = 23,
- // S41 = 6, S42 = 10, S43 = 15, S44 = 21;
- // string = utf8Encode(string);
- // x = convertToWordArray(string);
- // // console.log(JSON.stringify(x))
- // // console.log(x.length)
- // a = 0x67452301;
- // b = 0xEFCDAB89;
- // c = 0x98BADCFE;
- // d = 0x10325476;
- // for (k = 0; k < x.length; k += 16) {
- // AA = a;
- // BB = b;
- // CC = c;
- // DD = d;
- // a = FF(a, b, c, d, x[k + 0], S11, 0xD76AA478);
- // d = FF(d, a, b, c, x[k + 1], S12, 0xE8C7B756);
- // c = FF(c, d, a, b, x[k + 2], S13, 0x242070DB);
- // b = FF(b, c, d, a, x[k + 3], S14, 0xC1BDCEEE);
- // a = FF(a, b, c, d, x[k + 4], S11, 0xF57C0FAF);
- // d = FF(d, a, b, c, x[k + 5], S12, 0x4787C62A);
- // c = FF(c, d, a, b, x[k + 6], S13, 0xA8304613);
- // b = FF(b, c, d, a, x[k + 7], S14, 0xFD469501);
- // a = FF(a, b, c, d, x[k + 8], S11, 0x698098D8);
- // d = FF(d, a, b, c, x[k + 9], S12, 0x8B44F7AF);
- // c = FF(c, d, a, b, x[k + 10], S13, 0xFFFF5BB1);
- // b = FF(b, c, d, a, x[k + 11], S14, 0x895CD7BE);
- // a = FF(a, b, c, d, x[k + 12], S11, 0x6B901122);
- // d = FF(d, a, b, c, x[k + 13], S12, 0xFD987193);
- // c = FF(c, d, a, b, x[k + 14], S13, 0xA679438E);
- // b = FF(b, c, d, a, x[k + 15], S14, 0x49B40821);
- // a = GG(a, b, c, d, x[k + 1], S21, 0xF61E2562);
- // d = GG(d, a, b, c, x[k + 6], S22, 0xC040B340);
- // c = GG(c, d, a, b, x[k + 11], S23, 0x265E5A51);
- // b = GG(b, c, d, a, x[k + 0], S24, 0xE9B6C7AA);
- // a = GG(a, b, c, d, x[k + 5], S21, 0xD62F105D);
- // d = GG(d, a, b, c, x[k + 10], S22, 0x2441453);
- // c = GG(c, d, a, b, x[k + 15], S23, 0xD8A1E681);
- // b = GG(b, c, d, a, x[k + 4], S24, 0xE7D3FBC8);
- // a = GG(a, b, c, d, x[k + 9], S21, 0x21E1CDE6);
- // d = GG(d, a, b, c, x[k + 14], S22, 0xC33707D6);
- // c = GG(c, d, a, b, x[k + 3], S23, 0xF4D50D87);
- // b = GG(b, c, d, a, x[k + 8], S24, 0x455A14ED);
- // a = GG(a, b, c, d, x[k + 13], S21, 0xA9E3E905);
- // d = GG(d, a, b, c, x[k + 2], S22, 0xFCEFA3F8);
- // c = GG(c, d, a, b, x[k + 7], S23, 0x676F02D9);
- // b = GG(b, c, d, a, x[k + 12], S24, 0x8D2A4C8A);
- // a = HH(a, b, c, d, x[k + 5], S31, 0xFFFA3942);
- // d = HH(d, a, b, c, x[k + 8], S32, 0x8771F681);
- // c = HH(c, d, a, b, x[k + 11], S33, 0x6D9D6122);
- // b = HH(b, c, d, a, x[k + 14], S34, 0xFDE5380C);
- // a = HH(a, b, c, d, x[k + 1], S31, 0xA4BEEA44);
- // d = HH(d, a, b, c, x[k + 4], S32, 0x4BDECFA9);
- // c = HH(c, d, a, b, x[k + 7], S33, 0xF6BB4B60);
- // b = HH(b, c, d, a, x[k + 10], S34, 0xBEBFBC70);
- // a = HH(a, b, c, d, x[k + 13], S31, 0x289B7EC6);
- // d = HH(d, a, b, c, x[k + 0], S32, 0xEAA127FA);
- // c = HH(c, d, a, b, x[k + 3], S33, 0xD4EF3085);
- // b = HH(b, c, d, a, x[k + 6], S34, 0x4881D05);
- // a = HH(a, b, c, d, x[k + 9], S31, 0xD9D4D039);
- // d = HH(d, a, b, c, x[k + 12], S32, 0xE6DB99E5);
- // c = HH(c, d, a, b, x[k + 15], S33, 0x1FA27CF8);
- // b = HH(b, c, d, a, x[k + 2], S34, 0xC4AC5665);
- // a = II(a, b, c, d, x[k + 0], S41, 0xF4292244);
- // d = II(d, a, b, c, x[k + 7], S42, 0x432AFF97);
- // c = II(c, d, a, b, x[k + 14], S43, 0xAB9423A7);
- // b = II(b, c, d, a, x[k + 5], S44, 0xFC93A039);
- // a = II(a, b, c, d, x[k + 12], S41, 0x655B59C3);
- // d = II(d, a, b, c, x[k + 3], S42, 0x8F0CCC92);
- // c = II(c, d, a, b, x[k + 10], S43, 0xFFEFF47D);
- // b = II(b, c, d, a, x[k + 1], S44, 0x85845DD1);
- // a = II(a, b, c, d, x[k + 8], S41, 0x6FA87E4F);
- // d = II(d, a, b, c, x[k + 15], S42, 0xFE2CE6E0);
- // c = II(c, d, a, b, x[k + 6], S43, 0xA3014314);
- // b = II(b, c, d, a, x[k + 13], S44, 0x4E0811A1);
- // a = II(a, b, c, d, x[k + 4], S41, 0xF7537E82);
- // d = II(d, a, b, c, x[k + 11], S42, 0xBD3AF235);
- // c = II(c, d, a, b, x[k + 2], S43, 0x2AD7D2BB);
- // b = II(b, c, d, a, x[k + 9], S44, 0xEB86D391);
- // a = addUnsigned(a, AA);
- // b = addUnsigned(b, BB);
- // c = addUnsigned(c, CC);
- // d = addUnsigned(d, DD);
- // }
- // var temp = wordToHex(a) + wordToHex(b) + wordToHex(c) + wordToHex(d);
- // return temp.toUpperCase();
- // };
- // console.log('刘新修本地封装/md5加密(--测试--)', md5('测试'))
- //"DB06C78D1E24CF708A14CE81C9B617EC"
- /*** 第三方类库CryptoJS.MD5()方法 || 和中国文书网测试结果一致(小写) ***/
- console.log('刘新修/CryptoJS.MD5()-加密(--测试--)\n', CryptoJS.MD5('测试').toString())
- </script>
- </html>
中网文书网/MD5加密(--测试--) db06c78d1e24cf708a14ce81c9b617ec
刘新修/CryptoJS.MD5()-加密(--测试--) db06c78d1e24cf708a14ce81c9b617ec
发布专属环境SHELL脚本
- #ifconfig
- echo $projectPath
- echo $developer
- echo $rebuildBranch
- ### 获取最后一层的项目名称
- las_dir=$(basename "$projectPath")
- ### 提取上一层目录的全路径
- cur_dir=$(dirname $projectPath)
- ### 获取业务线的名称第二层
- pat_dir=$(basename "$cur_dir")
- echo $las_dir
- echo $cur_dir
- echo $pat_dir
- ### 通用前端发布脚本( 从本地同步来取 dist.tar.gz 文件包 ) ###
- wwwroot=/data/apps/nginx/htdocs/public/frontend$projectPath &&
- cd $wwwroot && pwd && git fetch && git checkout dev-$developer &&
- git pull origin dev-$developer &&
- bash /sh/downdist.sh /data/apps/nginx/htdocs/public/frontend$projectPath/upload/dynamicAssets.json /data/apps/nginx/htdocs/public/tarfile/XXX/$developer$projectPath http://dl.ktm1234.com/XXX/$developer$projectPath
- ### 通用前端发布脚本( 从本地同步来取 dist.tar.gz 文件包 ) ###
- wwwroot=/data/apps/nginx/htdocs/public/frontend$projectPath &&
- cd $wwwroot && pwd
- if [[ $rebuildBranch == true ]] ;then
- echo '---- 全新构建分支 ------'
- git checkout . && git checkout master &&
- git branch -D dev-$developer && git fetch &&
- git checkout -b dev-$developer origin/dev-$developer &&
- bash /sh/downdist.sh /data/apps/nginx/htdocs/public/frontend$projectPath/upload/dynamicAssets.json /data/apps/nginx/htdocs/public/tarfile/XXX/$developer$projectPath http://dl.ktm1234.com/XXX/$developer$projectPath
- else
- echo '---- 更新新版本 ------'
- git fetch && git checkout dev-$developer &&
- git checkout . && git pull origin dev-$developer &&
- bash /sh/downdist.sh /data/apps/nginx/htdocs/public/frontend$projectPath/upload/dynamicAssets.json /data/apps/nginx/htdocs/public/tarfile/XXX/$developer$projectPath http://dl.ktm1234.com/XXX/$developer$projectPath
- fi
Vue (preventReClick)防暴点 +防抖(debounce)和节流(throttle)函数
1. 防暴点(preventReClick)
- export default {
- install(Vue) {
- Vue.directive('preventReClick', {
- inserted: function (el, binding) {
- console.log(el.disabled)
- el.addEventListener('click', (e) => {
- if (!el.disabled) {
- el.disabled = true
- setTimeout(() => {
- el.disabled = false
- }, binding.value || 3000)
- //binding.value可以自行设置。如果设置了则跟着设置的时间走
- //例如:v-preventReClick='500'
- } else { // disabled为true时,阻止默认的@click事件
- e.preventDefault()
- e.stopPropagation()
- }
- })
- }
- }),
- }
- // 防止多次点击
- import preventReClick from '@/util/preventReClick '
- Vue.use(preventReClick);
- <div class="comment-btn" @click="submitMes()" v-preventReClick="3000">发送</div>
- <el-button @click="submitMes()" v-preventReClick="3000">发送</el-button>
2. 防抖(debounce)
- /**
- * @description 函数防抖 触发高频时间后n秒内函数只会执行一次,如果n秒内高频时间再次触发,则重新计算时间。
- * @param {Function} func 需要执行的函数
- * @param {Number} wait 间隔时间 默认200ms
- * @param {Boolean} immediate 是否立即执行 true(默认) 表立即执行,false 表非立即执行
- * @return {*}
- */
- export function VueDebounce(func, wait = 200, immediate = true) {
- let timeout = null; // 定时器
- return function () {
- let that = this, // this对象
- args = arguments; // 参数
- if (timeout) clearTimeout(timeout);
- if (immediate === true) { // 立即执行
- var callNow = !timeout;
- timeout = setTimeout(() => {
- timeout = null;
- }, wait)
- if (callNow) {
- // func.apply(that, args); // 普通用法
- that[func](...args); // vue用法
- }
- }
- else { // 非立即执行
- timeout = setTimeout(() => {
- // func.apply(this, args); // 普通用法
- that[func](...args); // vue用法
- }, wait);
- }
- }
- }
- import {VueDebounce} from "@/util/index"
- methods: {
- /**
- * 点击事件 函数防抖
- * 用法:<el-button @click="debounceHandel">点击测试</el-button>
- */
- debounceHandel: VueDebounce("handlerFunc"),
- /**
- * 点击事件:真正执行的函数
- */
- handlerFunc(type) {
- console.log("测试防抖事件");
- this.$emit("click","这是参数"); // 如果用普通用法,则这里会找不到$emit,因为this还往上继承了vue的对象
- },
- }
- * @description 函数节流
- * @param {Function} func 函数
- * @param {Number} wait 延迟执行毫秒数,默认200
- * @param {Number} type 1 表时间戳版,2 表定时器版
- */
- xport function VueThrottle(func, wait=200 ,type) {
- if(type===1){
- let previous = 0;
- }else if(type===2){
- let timeout;
- }
- return function() {
- let that= this;
- let args = arguments;
- if(type===1){
- let now = Date.now();
- if (now - previous > wait) {
- // func.apply(that, args); // 普通用法
- that[func](...args); // vue用法
- previous = now;
- }
- }else if(type===2){
- if (!timeout) {
- timeout = setTimeout(() => {
- timeout = null;
- // func.apply(that, args)
- that[func](...args); // vue用法
- }, wait)
- }
- }
- }
- import {VueThrottle} from "@/util/index"
- methods: {
- /**
- * 点击事件 函数防抖
- * 用法:<el-button @click="throttleHandel">点击测试</el-button>
- */
- throttleHandel: VueThrottle("handlerFunc"),
- /**
- * 点击事件:真正执行的函数
- */
- handlerFunc(type) {
- console.log("测试防抖事件");
- this.$emit("click","这是参数"); // 如果用普通用法,则这里会找不到$emit,因为this还往上继承了vue的对象
- },
- }
蓝盾发布平台,查看当前的版本号
- output(normal): BK_CI_GIT_REPO_HEAD_COMMIT_AUTHOR=刘新修
- output(normal): BK_CI_GIT_REPO_URL=http://172.16.101.177/health-product/health-front/health-manage-front.git
- output(except): bk_repo_type_e-9937698f8027470f86c86096e78e8940=GIT
- output(normal): BK_CI_GIT_REPO_NAME=health-product/health-front/health-manage-front
- output(except): git.health-product.health-front.health-manage-front.new.commit=c3084bed035f479b0e4419b20c00fe4cd25f0bac
Mock的基本语法及使用
- //定义/mock/index.js
- import Mock from 'mockjs'
- Mock.mock("/api/login", {
- code: 200,
- msg: "登陆成功",
- user: {
- name: "zeng8",
- score: 2048,
- rank: 10
- },
- token: "kjkjalsdiiuioayeuryqowierqiwerqowiery"
- })
- // url可以使用正则匹配
- // 拦截get请求,返回评论数据
- Mock.mock(/\/api\/feed/, "get", function(config) {
- //console.log("config" , config );
- //通过config可以获取到前端发给服务器的数据
- var po = config.url.indexOf("?"); //获取问号的位置
- if (po != -1) {
- var query = config.url.slice(po + 1); //获取到查询参数current=4转换为{current: 4}
- var arr = query.split("&"); //按&分割为数组
- var search = {}; //定义个对象
- arr.forEach(item => {
- var temp = item.split("="); //把数组每个元素按等于分割[current,4]
- search[temp[0]] = temp[1]; //search[ "current"] =4
- })
- }
- // 返回一个随机数据
- return Mock.mock({
- "code": 0,
- "data|4": [{
- id: "@id",
- msg: "@cparagraph(2,3)", //段落2-3行
- name: "@cname", //随机中文名
- date: "@datetime" //随机日期
- }],
- "pagnation": {
- "total|10-25": 1,
- "size": 4,
- "pageTotal|4-10": 1,
- "current": search.current,
- }
- })
- })
- Mock.mock("/api/test", Mock.mock({
- name: "@cname", //随机中文名
- "age|100-200": 1, //100-200的随机数
- "price|10-50.2-5": 1, //10-50随机数 小数点2-5位
- "live|1-2": true, //随机true或false
- "start|1-5": "⭐", //把字符串重复1-5次
- "friend|2": ["小红", "小明", "小刚", "小白", "小蓝"], //1是挑一个大于1是重复n次
- "props|1-3": {
- name: "mm",
- age: 22,
- leg: 2,
- job: "web",
- eye: 2
- },
- "tel": /13\d{9}/,
- "des": function() {
- return `大家好,我的名字是${this.name},今年${this.age}岁`
- },
- "data|10": [{
- "id|+1": 1024,
- "ID": "@id",
- date: "@date",
- time: "@time",
- datetime: "@datetime",
- name: "@cname",
- pic: "@dataImage('200x100')",
- description: "@cparagraph(1,3)",
- title: "@ctitle(8,12)",
- url: /http:\/\/www\.[a-z]{2,8}\.(com|cn|org)/,
- email: /[4-8]@\.(126|qq|163)\.(com|cn|org)/,
- address: "@county(true)", //省市区地址
- }]
- }))
main.js 文件
- /*** sleep ***/
- Vue.prototype.$sleep = time => {
- return new Promise((resolve, reject) => {
- window.setTimeout(() => {
- resolve(true)
- }, time)
- })
- }
增加测试页面
- <!--
- * @Description: npage.vue
- * @Version: 1.0
- * @Author: Jesse Liu
- * @Date: 2022-08-01 20:32:06
- * @LastEditors: Jesse Liu
- * @LastEditTime: 2023-09-07 13:24:11
- -->
- <template>
- <div class="wscn-http404-container">
- <h2 style="font-weight: normal; line-height: 160%;">userInfo ========= {{ userInfo }}</h2>
- <h2 style="font-weight: normal; line-height: 160%;">configInformation ========= {{ configInformation }}</h2>
- <h1 style="line-height:300px; text-align:center">npage.vue (新测试文件)</h1>
- <div>time:</div>
- </div>
- </template>
- <script>
- import { mapState } from "vuex";
- import { parseTime } from '@/utils'
- import { downloadFile } from "@/utils/getFile";
- export default {
- name: 'PageTest',
- computed: {
- ...mapState("user", ["userInfo","configInformation"]),
- message() {
- return 'PageTest'
- },
- parseTime: parseTime
- },
- mounted() {
- this.$store.dispatch("case/casesList/downloadFile",{}).then((res)=>{
- // let data = res.data;
- // let headers = res.headers;
- // /*** 调用下载文件 ***/
- // downloadFile(data, headers)
- })
- /*** 多定时器同时调用 ***/
- this.getStateA();
- this.getStateB();
- /*** 业务请求接口调用示例 ***/
- this.casePage();
- },
- methods: {
- /*** 定时器演示方法 ***/
- async getStateA(){
- /*** 定时器只管计算时间钩子标记 ***/
- console.log('sleepStateA ~~~ 开始')
- /*** 多定时处理任务A ***/
- console.time('sleepStateA');
- let sleepStateA = await this.$sleep(5000);
- console.log('sleepStateA ~~~ 结束', sleepStateA)
- console.timeEnd('sleepStateA');
- return sleepStateA;
- },
- /*** 定时器演示方法 ***/
- async getStateB(){
- /*** 定时器只管计算时间钩子标记 ***/
- console.log('sleepStateB ~~~ 开始')
- /*** 多定时处理任务B ***/
- console.time('sleepStateB');
- let sleepStateB = await this.$sleep(10000);
- console.log('sleepStateB ~~~ 结束', sleepStateB)
- console.timeEnd('sleepStateB');
- return sleepStateB;
- },
- /*** 模拟示例业务的状态 ***/
- async getCaseState(){
- /*** 定时器只管计算时间钩子标记 ***/
- let sleepStateCase = await this.$sleep(10000);
- return sleepStateCase;
- },
- /*** 模拟示例业务主方法 ***/
- async casePage(state = true, n = 0){
- /*** 定义及获取数据状态 ***/
- let runling = true;
- let getCaseState = await this.getCaseState();
- /*** 业务逻辑处理及使用 ***/
- if(state && getCaseState) {
- /*** 请求接口拿状态和后端约定状态码(根据状态码去更改runling的布尔值) ***/
- // 写你的vuex调用方法,如:this.$store.dispatch('user/record', {})
- /*** 以下代码是为了演示模拟3次请求后,状态变更,供参考 ***/
- /*** 假设后端接口告诉你可以终止执行调用的状态 (比如后端调用3次后就更改了状态) ***/
- let index = n;
- index +=1;
- console.log('第['+ index + ']次调用后端接口~~');
- if(index >= 3) {
- runling = false;
- }
- this.casePage(runling, index);
- }
- else{
- console.log('===========================================\n定时器已经结束关停,累计调用共: ' + n + '次~~');
- }
- }
- }
- }
- </script>
- <style lang="scss" scoped>
- </style>