标签 javascript 下的文章

错误描述

在使用uni-app开发微信小程序的时候,想要通过uni.chooseLocation获取用户地理位置的时候出现chooseLocation:fail the api need to be declared in the requiredPrivateInfos field in app.json/ext.json这样的错误。

错误分析

把错误日志分析下大致的意思就是:api需要在app.json/ext.json的requiredPrivateInfos字段中声明,也就是说需要app.json/ext.json在这里面配置下requiredPrivateInfos,那么怎么在uni-app里面配置呢?

解决办法

打开manifest.json选择源码视图,找到mp-weixin节点,添加requiredPrivateInfos的配置,源码如下:

"mp-weixin" : {
    "requiredPrivateInfos" : [ "chooseLocation", "getLocation" ]
}

然后问题就解决了,就可以正常获取用户的地理位置了。

我们都知道在我们进行浮点运算的时候经常遇到的一个麻烦事就是精度问题,在js里面,0.1+0.2等于0.30000000000000004。为了解决这种精度丢失的问题我们可以先给每个小数乘以100转为正数,在最后除以100还原为浮点数这样也行。不过我们也可以借助big.js来解决任意精度的大十进制算术运算。

首先安装big.js

  • 可以直接导入

    <script src='https://cdn.jsdelivr.net/npm/big.js@6.0.0/big.min.js'></script>
  • 也可以通过npm安装

    npm install big.js
    import Big from 'big.js';
  • 也可以下载后导入

    https://github.com/MikeMcl/big.js

计算

  • 加法plus

    0.1 + 0.2                                     // 0.30000000000000004
    const x = new Big (0.1);
    const y = x.plus (0.2);                      // 0.3
  • 减法minus

    0.3 - 0.1                                     // 0.19999999999999998   
    const x = new Big (0.3);
    const y = x.minus (0.1)                      // 0.2
  • 乘法times

    0.6 * 3                    // 1.7999999999999998
    x = new Big(0.6)
    y = x.times(3)             // '1.8'
  • 除法div

    x = new Big(0.9)
    y = new Big(0.1)
    x.div(y)                   // 9

    其他用法

  • 数字处理

    x = new Big(255.5)
    x.toExponential(5)                     // "2.55500e+2"
    x.toFixed(5)                           // "255.50000"
    x.toPrecision(5)                       // "255.50"
  • 判断是否相等

    Big(-0).eq(0)              // true  ( -0 === 0 )

小编今天在使用Vue播放视频的时候,发现视频的格式是flv的,但是video标签是不支持flv格式的,我们只有借助第三方的工具库了。感谢bilibili团队制作的flv.js工具库。
我们首先安装下

npm install --save flv.js

然后我们在组件里面引入

import flvjs from 'flv.js'

我们再在视图里面创建一个id为videoElement的video标签。

<video id="videoElement" controls autoplay muted style="width: 4.5rem; height: 3rem;" />

在mounted中使用flvjs

mounted() {
    if (flvjs.isSupported()) {
        let videoElement = document.getElementById('videoElement');
        let flvPlayer = flvjs.createPlayer({
            type: 'flv',
            isLive: true,
            hasAudio: false,
            url: 'https://XXXXXX.flv'
        });
        console.log(flvPlayer, 'flv对象')
        flvPlayer.attachMediaElement(videoElement);
        flvPlayer.load();
        flvPlayer.play();
    }
},

注意:

  1. flv.js工具库仅支持HTTPFLV协议的流,如果使用RTMP协议的流则依然需要使用flash插件。
  2. 如果没有包含音频流,hasAudio要设置为false。
  3. 如果要自动播放的话,由于浏览器禁用音频的自动播放,所以我们要在video标签上设置muted属性。
  4. 官方文档:https://github.com/bilibili/flv.js

今天在进行测试的时候,发现前端后端签名经常不一致,而且是在参数里面含有中文的时候才会出现这样的问题。为了排查问题,小编又找了几个第三方的md5加密工具,对需要签名的字符串进行加密,经过比较发现是前端出现了问题,后来小编又重新找了个加密文件,在这里跟大家分享下。具体的原理小编也没有深究,好像是需要将中文先转为utf-8。最后几行是在es6中导出使用的,如果需要自己解开注释。
源代码:

function md5(string) {
    function md5_RotateLeft(lValue, iShiftBits) {
        return (lValue << iShiftBits) | (lValue >>> (32 - iShiftBits));
    }

    function md5_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 md5_F(x, y, z) {
        return (x & y) | ((~x) & z);
    }

    function md5_G(x, y, z) {
        return (x & z) | (y & (~z));
    }

    function md5_H(x, y, z) {
        return (x ^ y ^ z);
    }

    function md5_I(x, y, z) {
        return (y ^ (x | (~z)));
    }

    function md5_FF(a, b, c, d, x, s, ac) {
        a = md5_AddUnsigned(a, md5_AddUnsigned(md5_AddUnsigned(md5_F(b, c, d), x), ac));
        return md5_AddUnsigned(md5_RotateLeft(a, s), b);
    };

    function md5_GG(a, b, c, d, x, s, ac) {
        a = md5_AddUnsigned(a, md5_AddUnsigned(md5_AddUnsigned(md5_G(b, c, d), x), ac));
        return md5_AddUnsigned(md5_RotateLeft(a, s), b);
    };

    function md5_HH(a, b, c, d, x, s, ac) {
        a = md5_AddUnsigned(a, md5_AddUnsigned(md5_AddUnsigned(md5_H(b, c, d), x), ac));
        return md5_AddUnsigned(md5_RotateLeft(a, s), b);
    };

    function md5_II(a, b, c, d, x, s, ac) {
        a = md5_AddUnsigned(a, md5_AddUnsigned(md5_AddUnsigned(md5_I(b, c, d), x), ac));
        return md5_AddUnsigned(md5_RotateLeft(a, s), b);
    };

    function md5_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 = 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 md5_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);
            WordToHexValue = WordToHexValue + WordToHexValue_temp.substr(WordToHexValue_temp.length - 2, 2);
        }
        return WordToHexValue;
    };

    function md5_Utf8Encode(string) {
        string = 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 = Array();
    var k, AA, BB, CC, DD, a, b, c, d;
    var S11 = 7,
        S12 = 12,
        S13 = 17,
        S14 = 22;
    var S21 = 5,
        S22 = 9,
        S23 = 14,
        S24 = 20;
    var S31 = 4,
        S32 = 11,
        S33 = 16,
        S34 = 23;
    var S41 = 6,
        S42 = 10,
        S43 = 15,
        S44 = 21;
    string = md5_Utf8Encode(string);
    x = md5_ConvertToWordArray(string);
    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 = md5_FF(a, b, c, d, x[k + 0], S11, 0xD76AA478);
        d = md5_FF(d, a, b, c, x[k + 1], S12, 0xE8C7B756);
        c = md5_FF(c, d, a, b, x[k + 2], S13, 0x242070DB);
        b = md5_FF(b, c, d, a, x[k + 3], S14, 0xC1BDCEEE);
        a = md5_FF(a, b, c, d, x[k + 4], S11, 0xF57C0FAF);
        d = md5_FF(d, a, b, c, x[k + 5], S12, 0x4787C62A);
        c = md5_FF(c, d, a, b, x[k + 6], S13, 0xA8304613);
        b = md5_FF(b, c, d, a, x[k + 7], S14, 0xFD469501);
        a = md5_FF(a, b, c, d, x[k + 8], S11, 0x698098D8);
        d = md5_FF(d, a, b, c, x[k + 9], S12, 0x8B44F7AF);
        c = md5_FF(c, d, a, b, x[k + 10], S13, 0xFFFF5BB1);
        b = md5_FF(b, c, d, a, x[k + 11], S14, 0x895CD7BE);
        a = md5_FF(a, b, c, d, x[k + 12], S11, 0x6B901122);
        d = md5_FF(d, a, b, c, x[k + 13], S12, 0xFD987193);
        c = md5_FF(c, d, a, b, x[k + 14], S13, 0xA679438E);
        b = md5_FF(b, c, d, a, x[k + 15], S14, 0x49B40821);
        a = md5_GG(a, b, c, d, x[k + 1], S21, 0xF61E2562);
        d = md5_GG(d, a, b, c, x[k + 6], S22, 0xC040B340);
        c = md5_GG(c, d, a, b, x[k + 11], S23, 0x265E5A51);
        b = md5_GG(b, c, d, a, x[k + 0], S24, 0xE9B6C7AA);
        a = md5_GG(a, b, c, d, x[k + 5], S21, 0xD62F105D);
        d = md5_GG(d, a, b, c, x[k + 10], S22, 0x2441453);
        c = md5_GG(c, d, a, b, x[k + 15], S23, 0xD8A1E681);
        b = md5_GG(b, c, d, a, x[k + 4], S24, 0xE7D3FBC8);
        a = md5_GG(a, b, c, d, x[k + 9], S21, 0x21E1CDE6);
        d = md5_GG(d, a, b, c, x[k + 14], S22, 0xC33707D6);
        c = md5_GG(c, d, a, b, x[k + 3], S23, 0xF4D50D87);
        b = md5_GG(b, c, d, a, x[k + 8], S24, 0x455A14ED);
        a = md5_GG(a, b, c, d, x[k + 13], S21, 0xA9E3E905);
        d = md5_GG(d, a, b, c, x[k + 2], S22, 0xFCEFA3F8);
        c = md5_GG(c, d, a, b, x[k + 7], S23, 0x676F02D9);
        b = md5_GG(b, c, d, a, x[k + 12], S24, 0x8D2A4C8A);
        a = md5_HH(a, b, c, d, x[k + 5], S31, 0xFFFA3942);
        d = md5_HH(d, a, b, c, x[k + 8], S32, 0x8771F681);
        c = md5_HH(c, d, a, b, x[k + 11], S33, 0x6D9D6122);
        b = md5_HH(b, c, d, a, x[k + 14], S34, 0xFDE5380C);
        a = md5_HH(a, b, c, d, x[k + 1], S31, 0xA4BEEA44);
        d = md5_HH(d, a, b, c, x[k + 4], S32, 0x4BDECFA9);
        c = md5_HH(c, d, a, b, x[k + 7], S33, 0xF6BB4B60);
        b = md5_HH(b, c, d, a, x[k + 10], S34, 0xBEBFBC70);
        a = md5_HH(a, b, c, d, x[k + 13], S31, 0x289B7EC6);
        d = md5_HH(d, a, b, c, x[k + 0], S32, 0xEAA127FA);
        c = md5_HH(c, d, a, b, x[k + 3], S33, 0xD4EF3085);
        b = md5_HH(b, c, d, a, x[k + 6], S34, 0x4881D05);
        a = md5_HH(a, b, c, d, x[k + 9], S31, 0xD9D4D039);
        d = md5_HH(d, a, b, c, x[k + 12], S32, 0xE6DB99E5);
        c = md5_HH(c, d, a, b, x[k + 15], S33, 0x1FA27CF8);
        b = md5_HH(b, c, d, a, x[k + 2], S34, 0xC4AC5665);
        a = md5_II(a, b, c, d, x[k + 0], S41, 0xF4292244);
        d = md5_II(d, a, b, c, x[k + 7], S42, 0x432AFF97);
        c = md5_II(c, d, a, b, x[k + 14], S43, 0xAB9423A7);
        b = md5_II(b, c, d, a, x[k + 5], S44, 0xFC93A039);
        a = md5_II(a, b, c, d, x[k + 12], S41, 0x655B59C3);
        d = md5_II(d, a, b, c, x[k + 3], S42, 0x8F0CCC92);
        c = md5_II(c, d, a, b, x[k + 10], S43, 0xFFEFF47D);
        b = md5_II(b, c, d, a, x[k + 1], S44, 0x85845DD1);
        a = md5_II(a, b, c, d, x[k + 8], S41, 0x6FA87E4F);
        d = md5_II(d, a, b, c, x[k + 15], S42, 0xFE2CE6E0);
        c = md5_II(c, d, a, b, x[k + 6], S43, 0xA3014314);
        b = md5_II(b, c, d, a, x[k + 13], S44, 0x4E0811A1);
        a = md5_II(a, b, c, d, x[k + 4], S41, 0xF7537E82);
        d = md5_II(d, a, b, c, x[k + 11], S42, 0xBD3AF235);
        c = md5_II(c, d, a, b, x[k + 2], S43, 0x2AD7D2BB);
        b = md5_II(b, c, d, a, x[k + 9], S44, 0xEB86D391);
        a = md5_AddUnsigned(a, AA);
        b = md5_AddUnsigned(b, BB);
        c = md5_AddUnsigned(c, CC);
        d = md5_AddUnsigned(d, DD);
    }
    return (md5_WordToHex(a) + md5_WordToHex(b) + md5_WordToHex(c) + md5_WordToHex(d)).toLowerCase();
}

# es6导出使用
//module.exports = {
//    md5: md5
//}

JavaScript打乱一个数组的顺序的两种方式

  • 方法一:利用sort函数

      arr.sort(function() {
          return .5 - Math.random();
      });

    这种方式可以打乱一个数组的顺序,但是并不是真正的乱序,所以建议不要用在严谨的打乱顺序上。

  • 方法二:自己封装一个函数

    function rand(arr) {
          var len = arr.length
          //倒叙遍历该数组
          for(var i = arr.length - 1; i >= 0; i--) {
              // 产生一个在数字长度内的随机数
              var randomIndex = Math.floor(Math.random() * (i + 1));
              // 作为数组下标去取数组该位置的值
              var itemIndex = arr[randomIndex];
              // 随机的位置与该位置互换
              arr[randomIndex] = arr[i];
              arr[i] = itemIndex;
          }
          return arr;
      }

对于一些很大的数字在前端显示的时候可能会不容易控制,而且对于一些很大的数字我们也不需要很精确的显示,这时候我们就需要把这个阿拉伯数字转换为汉字形式的了,并且保留一位小数就可以了。比如:12000我们可以显示为1.2万
我们之前说了下加逗号进行区分的方法,大家可以看下小编之前的文章。
我们来说下如何实现的吧

function makeFriendly(num) {
    if (num >= 100000000) {
        num = Math.round(num / 10000000) / 10 + '亿'
    } else if (num >= 10000) {
        num = Math.round(num / 1000) / 10 + '万'
    }
    return num;
}

nyroMd.jpg

在我们程序处理金钱的时候,有时候在使用JavaScript的计算的时候很容易出现问题,如果数字很大的话往往会出现显示不好看的问题,所以小编在这里封装了一个格式化金钱的方法。

function formatCurrency(num, withcents) {
    var originnum = num;
    num = num.toString().replace(/\$|\,/g, '');
    if (isNaN(num)) {
        num = "0";
    }
    var sign = (num == (num = Math.abs(num)));
    num = Math.floor(num * 100 + 0.50000000001);
    var cents = num % 100;
    num = Math.floor(num / 100).toString();
    if (cents < 10) {
        cents = "0" + cents;
    }
    for (var i = 0; i < Math.floor((num.length - (1 + i)) / 3); i++) {
        num = num.substring(0, num.length - (4 * i + 3)) + ',' + num.substring(num.length - (4 * i + 3));
    }
    var rs = (((sign) ? '' : '-') + num + '.' + cents);
    if (!withcents && parseInt(originnum) == parseFloat(originnum)) {
        return rs.split('.')[0];
    } else {
        return rs;
    }
}

参数:

  • num:金钱的金额
  • withcents:是否补全分(即小数点后的两位)

  1. 首先引入jquery

    <script src="https://cdn.bootcss.com/jquery/3.2.1/jquery.min.js"></script>
  2. 准备html标签

    <input type="file" id="picFile" onchange="readFile(this)"/>
    <img style="" id="img" src="" alt="" />
  3. javascript代码用户图片的压缩

    function readFile(obj){
     var file = obj.files[0];
     //判断类型是不是图片
       if(!/image\/\w+/.test(file.type)){
           alert("你上传的不是图片");
           return false;
       }
       var reader = new FileReader();
       reader.readAsDataURL(file);
       reader.onload = function(e){
           dealImage(this.result,{width:200},function(base){
               document.getElementById('img').setAttribute('src',base)
           });
       }
     }
     //PC端传入的可以是相对路径,但是移动端必须是绝对路径
     //callback 回调函数,必须带有base64字符串的参数
     //obj 可选值width, height, quality
    function dealImage(path, obj, callback){
       var img = new Image();
       img.src = path;
       img.onload = function(){
           var that = this;
           // 默认按比例压缩
           var w = that.width,
               h = that.height,
               scale = w / h;
           w = obj.width || w;
           h = obj.height || (w / scale);
           var quality = 1; // 值越大越清楚
           //生成canvas
           var canvas = document.createElement('canvas');
           var ctx = canvas.getContext('2d');
           // 创建属性节点
           var anw = document.createAttribute("width");
           anw.nodeValue = w;
           var anh = document.createAttribute("height");
           anh.nodeValue = h;
           canvas.setAttributeNode(anw);
           canvas.setAttributeNode(anh);
           ctx.drawImage(that, 0, 0, w, h);
           // 图像质量
           if(obj.quality && obj.quality <= 1 && obj.quality > 0){
               quality = obj.quality;
           }
           // quality值越小,所绘制出的图像越模糊
           var base64 = canvas.toDataURL('image/jpeg', quality );
           // 回调函数返回base64的值
           callback(base64);
       }
     }

第一步:首先引入jquery.min.js和jquery.qrcode.min.js

   <script src="http://libs.baidu.com/jquery/1.8.3/jquery.min.js"></script>
   <script type="text/javascript" src="http://cdn.staticfile.org/jquery.qrcode/1.0/jquery.qrcode.min.js"></script>

第二步:确定输入内容

<input type="text" id="con"> <button id="btn">生成</button>

第三步:生成二维码
第一种方式:canvas方式:

  在需要显示的地方

<div id="code"></div>

  
  第二步:生成
  ```
    $("#btn").click(function () {
        $('#code').qrcode( $("#con").val());
    })
  ```

第二方式:table方式:

  生成:
  ```
       $("#btn").click(function () {
    $("#code").qrcode({
        render: "table", 
        width: 200, 
        height:200, 
        text: $("#con").val() 
    });
    $('#code').qrcode( );
})
```

注意:中文的话,必须先转换为utf-8编码

function toUtf8(str) {
       var out, i, len, c;
       out = "";
       len = str.length;
       for(i = 0; i < len; i++) {
           c = str.charCodeAt(i);
           if ((c >= 0x0001) && (c <= 0x007F)) {
               out += str.charAt(i);
           } else if (c > 0x07FF) {
               out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F));
               out += String.fromCharCode(0x80 | ((c >>  6) & 0x3F));
               out += String.fromCharCode(0x80 | ((c >>  0) & 0x3F));
           } else {
               out += String.fromCharCode(0xC0 | ((c >>  6) & 0x1F));
               out += String.fromCharCode(0x80 | ((c >>  0) & 0x3F));
           }
       }
       return out;
   }

示例代码:

 <!doctype html>
<html lang="en">
<head>
   <meta charset="UTF-8">
   <meta name="viewport"
         content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
   <meta http-equiv="X-UA-Compatible" content="ie=edge">
   <title>Document</title>
   <script src="http://libs.baidu.com/jquery/1.8.3/jquery.min.js"></script>
   <script type="text/javascript" src="http://cdn.staticfile.org/jquery.qrcode/1.0/jquery.qrcode.min.js"></script>
</head>
<body>
<input type="text" id="con"> <button id="btn">生成</button>
<div id="code"></div>
</body>
</html>
<script>
   $("#btn").click(function () {
       $("#code").qrcode({
           render: "table",
           width: 200,
           height:200,
           text: toUtf8($("#con").val())
       });
       $('#code').qrcode( );
   })
   function toUtf8(str) {
       var out, i, len, c;
       out = "";
       len = str.length;
       for(i = 0; i < len; i++) {
           c = str.charCodeAt(i);
           if ((c >= 0x0001) && (c <= 0x007F)) {
               out += str.charAt(i);
           } else if (c > 0x07FF) {
               out += String.fromCharCode(0xE0 | ((c >> 12) & 0x0F));
               out += String.fromCharCode(0x80 | ((c >>  6) & 0x3F));
               out += String.fromCharCode(0x80 | ((c >>  0) & 0x3F));
           } else {
               out += String.fromCharCode(0xC0 | ((c >>  6) & 0x1F));
               out += String.fromCharCode(0x80 | ((c >>  0) & 0x3F));
           }
       }
       return out;
   }
</script>

Vue-Cli3.0没有了config文件夹,默认也没有配置文件,这些都是需要我们手动进行建立的,首先我们需要在项目根目录里面建议一个vue.config.js的文件,名字必须是vue.config.js。然后在这个js文件里面进行配置,小编在下面简单介绍几个常用的配置,以及写法:

module.exports={
    baseUrl:'/',//根路径
    outputDir:'dist',//构建输出目录
    assetsDir:'assets',//静态资源目录
    lintOnSave:false,//是否开启eslint保存检测,有效值:true || false || 'error'
    devServer:{
        open:true,//是否自动打开页面
        host:"127.0.0.1",//主机名(真机测试0.0.0.0)
        port:8081,//端口号
        https:false,//是否开启https
        hotOnly: false,//热更新
        proxyL:{
            //配置跨域
            '/api':{
                target:'http://localhost:5000/api',
                ws:true,
                changeOrigin:true,
                pathRewrite:{
                    '^/api':''
                }
            }
        },
        before(app){
            //在服务内部所有中间件之前执行的印个内容
            app.get('/api',(req,res)=>{
                res.json();
            })
        }
    }
}