美文网首页
工作总结3.0

工作总结3.0

作者: 牛奶是本命___ | 来源:发表于2022-08-30 14:50 被阅读0次

    一、通用

    • ajax

    原生ajax封装

    ajax({
          url: bms_api + '/member/getPayResultCycle',
          type: 'POST',
          header: {
            Authorization: token, // 用户token,过期重新登录
            tenant: tenant, // 租户区分渠道
          }
    }
    
    function ajax(opt) {
      // console.log(opt.api.api)
      !opt.type ? opt.type = 'get' : null; // 默认get请求
      !opt.async ? opt.async = true : null; // 异步会阻断程序
    
      var xmlHttp = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('microsoft.XMLHTTP');
      // xmlHttp.timeout = opt.timeout ? opt.timeout : 5000;
      var API = opt.api;
    
      var url = IPCONFIG.base + PORTCONFIG[API['class']] + API['class'] + '_api' + API.api;
    
      if (!opt.params["timestamp"]) {
        opt.params["timestamp"] = new Date().getTime();
      }
      var postData = setURLparams(opt.params);
    
      // console.log(opt.api)
    
      if (opt.type.toUpperCase() === 'POST') {
        xmlHttp.open(opt.type, url, opt.async);
        xmlHttp.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded;charset=utf-8');
        if (opt.header) {
          for (var item in opt.header) {
            xmlHttp.setRequestHeader(item, opt.header[item]);
          }
        }
        xmlHttp.setRequestHeader('tenant',tenant);
        xmlHttp.send(postData);
      } else if (opt.type.toUpperCase() === 'GET') {
        url = url + '?' + postData;
        xmlHttp.open(opt.type, url, opt.async);
        // 只有需要token的接口传自定义header
        if (API['class'] == 'urm' || API['class'] == 'crm') {
          // console_log("API['class'] "+API['class']+' '+API.api);
          if (opt.header) {
            for (var item in opt.header) {
              xmlHttp.setRequestHeader(item, opt.header[item]);
            }
          }
          xmlHttp.setRequestHeader('tenant',tenant);
        }
        xmlHttp.send(null);
      }
      xmlHttp.onreadystatechange = function () {
        if (xmlHttp.readyState == 4) {
          dataHandler(xmlHttp, opt);
        } else {
          // 请求中。。。
          // console.log(url, xmlHttp.readyState, xmlHttp.status)
        }
      };
      // xmlHttp.ontimeout = function () {
      //   console_log('ontimeout: '+opt.api.errorCode+' '+xmlHttp.status);
      //   if (typeof opt.error != 'undefined') {
      //     opt.error(xmlHttp);
      //   } else if (opt.api.errorCode) {
      //     // 请求失败
      //     BadGateWay({
      //       code: opt.api.errorCode,
      //       status: xmlHttp.status,
      //     });
      //   }
      // }
    }
    
    • ajax自定义header跨域问题

    问题原因
    添加自定义header会导致发送ajax后浏览器自动先发送一个预检请求(OPTIONS),预检请求中的内容是空的,所有后端的拦截器不需要对预检请求中的数据进行校验,此时的校验肯定是不通过的,导致拦截器无法放行,后续的实际请求就无法发送了,浏览器就会认为跨域出现了问题,所以就产生了跨域问题.

    在设置了自定义header后,浏览器到后端请求将分为两步进行

    1.发送预请求 OPTIONS 请求
    浏览器将先发送一个预请求OPTIONS到后端,这里后端需要对OPTIONS请求做出正确响应,可以直接返回200(我司是204)状态码,不用返回内容信息。

    2.发送真正的数据请求
    浏览器接收到OPTIONS正确响应后会自动执行发送get或post请求。可此时依旧没有请求到后端数据,F12查看控制台输出,会发现报错了。这就是接下来要处理的跨域问题。

    • 跨域的处理主要是服务器端设置响应头

    Access-Control-Allow-Origin; //支持全域名访问,不安全,部署后需要固定限制为客户端网址
    Access-Control-Allow-Methods; //支持的http 动作
    Access-Control-Allow-Headers; //响应头 请按照自己需求添加

    header("Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Authorization, tenant");
    
    lQLPJxZiSE3YHfXNAQ3NA4mw3V4s90wBVnkCohedpcDWAA_905_269.png
    • ie浏览器兼容问题
      Access-Control-Allow-Headers多行设置或者配的值有空格就会报错请求不通
    lQLPJxZi8-lynFHMts0EzrAWsA3ei8QOZQKjMMfLgPgA_1230_182.png
    • 尺寸适配

      1. rem

    rem是CSS3新增的一个相对单位(root em,根em)
    1rem=根元素html的font-size值。当页面中所有元素都使用rem单位时,你只需要改变根元素font-size值,所有元素就会按比例放大或者缩小。因此我们只需要写一小段js代码,根据屏幕宽度改变html的font-size值,就可以做到弹性布局。这种方法确实便捷,兼容性也很好,是目前非常主流的弹性布局方案。
    rem布局的本质是等比缩放,一般是基于宽度

    弊端与优点
    弊端之一:和根元素font-size值强耦合,系统字体放大或缩小时,会导致布局错乱
    弊端之二:html文件头部需插入一段js代码
    rem的优点:移动端rem布局比vw主流的原因 兼容性
    vw单位兼容性比rem稍差,ios8、安卓4.4及以上才完全支持。

    2. vw

    w3c的官方解释
    viewpoint width,视窗宽度,1vw=视窗宽度的1%
    viewpoint height,视窗高度,1vh=视窗高度的1%

    viewport即浏览器可视区域大小
    我们可以这样理解 100vw = window.innerwidth, 100vh = window.innerheight
    在移动端我们一般都可以认为,100vw就是屏幕宽度。若使用vw布局,就不需要再像rem那样,在js中去动态设置根元素的font-size了,sass中只需要使用这个函数做转换即可

    //以iphone7尺寸@2x 750像素宽的视觉稿为例
    @function vw($px) {
        @return ($px / 750) * 100vw;
    }
     
    //假设一个div元素在视觉稿中,宽度为120px,字体大小为12px
    div {
        width: vw(120);
        font-size: vw(12);
    }
    

    vw单位和百分比%单位对比
    百分比%是根据父元素宽度或者高度进行计算,而vw vh固定按照viewport来计算,不会受父元素宽高度影响。
    100vw包括了页面滚动条宽度(页面滚动条属于viewport范围内,100vw当然包括了页面滚动条宽度)。但把body或者html设置为width:100%时,是不包括页面滚动条的宽度的。也就是说100vw在有纵向滚动条的情况下,会比100%宽

    3. 媒体查询

    @media是css3的新属性,它的原理是监控移动端设备的宽度,然后根据不同的宽度,适配不同的css样式,来实现移动端适配

    应用场景:
    部分pad屏幕高度较小,单独调整垂直间距
    小米小爱pad新设备-6寸屏 960x480

    @media screen and (max-height: 540px) {
        .content .title .title2 {
            margin-top: -0.7rem;
        }
        .content .durationArea {
            top: 1.8rem;
        }
        .explanation {
            top: 7.24rem;
        }
    }
    
    • android ios交互

      1. android

      // 获取参数
      var params = android.getData();
      var paramsObj = JSON.parse(params);
      var versionName = android.getVersionName();
      packageName = android.getPackageName()
    // 方法调用
    // 按返回-关闭h5
    android.isFinish(true);
    // 按返回-上一页h5
    android.isFinish(false);
    

    2. ios

    DSBridge

    DSBridge是目前地球上最好的IOS/Android javascript bridge. DSBridge有四大特点: 支持同步调用、跨平台、三端皆易用。

    bridge.call(method,[args,callback])
    功能:调用Native api
    method: api函数名
    args:参数,类型:json, 可选参数
    callback(String returnValue):仅调用异步api时需要

    html
    <script src="./dsbridge.js"></script>
    
    js
    // 接收参数 同步
        if (isIOS) {
            var res = dsBridge.call("getParam","getData");
            var params = JSON.parse(res);
            paramObj = params;
        } else if (typeof android === 'object') {
            var params = android.getParam();
            paramObj = JSON.parse(params);
        }
    // 异步
    // 对于一些比较耗时的api, DSBridge提供了异步支持,正如上面代码所示,此时你需要传一个回调(如果没有参数,回调可作为第二个参数),当api完成时回调将会被调用,结果以字符串的形式传递。
        dsBridge.call("getParam","getData", function (res) {
            console.log(res);
        })
    
    // 回传
        if (isIOS) {
            dsBridge.call("setOrderNum", code, function (res) {
               console.log(res);
            });
        } else if (typeof android === 'object') {
            android.setOrderNum(code);
        }
    
    • h5支付

    场景:app内嵌页 支付宝、微信支付
    ios上线审核

    function wechatPay() { // 微信支付
        selects.payType = 2;
        console.log(selects);
        $('.pay1').addClass('select');
        $('.pay2').removeClass('select');
    }
    
    function aliPay() { //支付宝支付
        selects.payType = 1;
        console.log(selects);
        $('.pay2').addClass('select');
        $('.pay1').removeClass('select');
    }
    
    function goPay(code) {
        var timestamp = Date.parse(new Date());
        console.log('timestamp:'+timestamp);
        ajax({
            url: bms_api+'/member/createPrePayOrder',
            type: 'post',
            header: {
                'Authorization': paramObj.token 
            },
            params: {
                preOrderCode: code,
                ip: IP,
                requestTime: timestamp,
                payType: selects.payType,
                tradeType: 'MWEB',
            },
            success: function (data) {
                if(data.retCode == '00000000') {
                    console.log(data);
                    if (data.retMsg.form) { // 支付宝
                        var content = $('.confirm');
                        var div = creatDom('div', content);
                        div.innerHTML = (data.retMsg.form);  //res.data是返回的表单
                        var forms = document.getElementsByTagName('form');
                        console.log(forms);
                        document.forms[0].submit();
                    } else if (data.retMsg.mweb_url) {// 微信
                        location.href = data.retMsg.mweb_url;
                        payResult();
                    }
                } else {
                    var toast = data.retMsg;
                    showToast(toast);
                }
                isClick = true;
            },
            error: function (err) {
                console.log(err);
                isClick = true;
                var toast = '服务器开小差';
                showToast(toast);
            }
        })
    }
    

    二、微信小程序

    • ios显示时间为NaN

    小程序中的时间数据在安卓上能正常显示,但在ios系统上会显示NaN
    原因是ios不支持在数据库中传递 2019-07-02这种格式的日期,必须转换为2019/07/02这种格式才会显示正常;

          data.retInfo.activityList.forEach((item,index) => {
                // console.log(new Date(item.expireTime.replace(/-/g, "/")).getTime());
                // console.log(Number(new Date(item.expireTime.replace(/-/g, "/")))); 
                if(new Date(item.expireTime.replace(/-/g, "/")).getTime() < new Date(data.retInfo.serverTime.replace(/-/g, "/")).getTime()) {
                  item.isEnd = 1
                } else {
                  item.isEnd = 0
                }
          })
    

    相关文章

      网友评论

          本文标题:工作总结3.0

          本文链接:https://www.haomeiwen.com/subject/ccupqktx.html