访问总计的HTML5的新本性,基本除了IE9以下都能够选拔。

=====================================================================

旧版本中:dev-server.js 这段去掉

 

*前端质量监察和控制系列:* 预览地址

var apiRoutes = express.Router()
//getList
apiRoutes.get('/getDiscList', function (req, res) {
  var url = 'https://c.y.qq.com/splcloud/fcgi-bin/fcg_get_diss_by_tag.fcg'
  axios.get(url, {
    headers: {
      referer: 'https://c.y.qq.com/',
      host: 'c.y.qq.com'
    },
    params: req.query
  }).then((response) => {
    res.json(response.data)
  }).catch((e) => {
    console.log(e)
  })
})
//lyric
apiRoutes.get('/lyric', function (req, res) {
  var url = 'https://c.y.qq.com/lyric/fcgi-bin/fcg_query_lyric_new.fcg'

  axios.get(url, {
    headers: {
      referer: 'https://c.y.qq.com/',
      host: 'c.y.qq.com'
    },
    params: req.query
  }).then((response) => {
    var ret = response.data
    if (typeof ret === 'string') {
      var reg = /^\w+\(({[^()]+})\)$/
      var matches = ret.match(reg)
      if (matches) {
        ret = JSON.parse(matches[1])
      }
    }
    res.json(ret)
  }).catch((e) => {
    console.log(e)
  })
})
//use
app.use('/api', apiRoutes)

HTML5语法

=====================================================================

 

超越四分之二世襲了html的语法

  对于前端选取来说,Js错误的发生径直影响前端采纳的品质。对前面一个极度的监察和控制是整整前端监察和控制体系中的贰个重要环节。
那么怎么样完毕对Js错误的督察呢?对采摘到的js错误,我们该怎么去解析呢?解析的结果该怎么着展示呢?那个题目将直接涉及到是或不是能够监察和控制和分出去有价值的多寡。

在 新的 webpack.dev.config.js 中 添加

分裂之处:开始的
<!DOCTYPE html>

  首先,我们应该对Js报错情况有个大约的垂询,那样才可以即时的垂询前端项目标健康情形。所以大家须要解析出部分不可缺少的数目。

    //-------------------axios 结合 node.js 代理后端请求 start
const express = require('express')
const axios = require('axios')
const app = express()
var apiRoutes = express.Router()
app.use('/api', apiRoutes)
    //-------------------axios 结合 node.js 代理后端请求 end

const devWebpackConfig = merge(baseWebpackConfig, {
    module: {
        rules: utils.styleLoaders({ sourceMap: config.dev.cssSourceMap, usePostCSS: true })
    },
    // cheap-module-eval-source-map is faster for development
    devtool: config.dev.devtool,

    // these devServer options should be customized in /config/index.js
    devServer: {
        clientLogLevel: 'warning',
        historyApiFallback: {
            rewrites: [
                { from: /.*/, to: path.posix.join(config.dev.assetsPublicPath, 'index.html') },
            ],
        },
        //----------------axios 结合 node.js 代理后端请求
        before(app) {
            // 推荐热门歌单
            app.get('/api/getDiscList', function(req, res) {
                var url = 'https://c.y.qq.com/splcloud/fcgi-bin/fcg_get_diss_by_tag.fcg'
                axios.get(url, {
                    headers: {
                        referer: 'https://c.y.qq.com/',
                        host: 'c.y.qq.com'
                    },
                    params: req.query
                }).then((response) => {
                    res.json(response.data)
                }).catch((e) => {
                    console.log(e)
                })
            })
        },
        //----------------axios 结合 node.js 代理后端请求
        hot: true,
        contentBase: false, // since we use CopyWebpackPlugin.
        compress: true,
        host: HOST || config.dev.host,
        port: PORT || config.dev.port,
        open: config.dev.autoOpenBrowser,
        overlay: config.dev.errorOverlay ? { warnings: false, errors: true } : false,
        publicPath: config.dev.assetsPublicPath,
        proxy: config.dev.proxyTable,
        quiet: true, // necessary for FriendlyErrorsPlugin
        watchOptions: {
            poll: config.dev.poll,
        }
    },
    plugins: [
        new webpack.DefinePlugin({
            'process.env': require('../config/dev.env')
        }),
        new webpack.HotModuleReplacementPlugin(),
        new webpack.NamedModulesPlugin(), // HMR shows correct file names in console on update.
        new webpack.NoEmitOnErrorsPlugin(),
        // https://github.com/ampedandwired/html-webpack-plugin
        new HtmlWebpackPlugin({
            filename: 'index.html',
            template: 'index.html',
            inject: true
        }),
        // copy custom static assets
        new CopyWebpackPlugin([{
            from: path.resolve(__dirname, '../static'),
            to: config.dev.assetsSubDirectory,
            ignore: ['.*']
        }])
    ]
})

<html
lang=”zh-CN”>

  如:黄金时代段时间内,应用JS报错的增势(chart图表)、JS错误发生率、JS错误在PC端发生的票房价值、JS错误在IOS端爆发的可能率、JS错误在Android端发生的概率,以至JS错误的归类。

 

<meta
charset=”utf-8″>

  然后,大家再去当中的Js错误实行详尽的深入分析,扶助大家每种考察出错的职位和发生错误的因由。

字符编码变得不难,

  如:JS错误类型、
JS错误音讯、JS错误仓库、JS错误产生的岗位以至相关任务的代码;JS错误发生的可能率、浏览器的等级次序,版本号,设备机型等等协助新闻

不区分轻重缓急写,

意气风发、JS Error 监控作用 (数据大概浏览)

图片 1

 

为了获取那些数量,大家必要在上传的时候将其解析出来。在无数日志解析中,非常多字段及功用是双重通用的,所以应当将其包装起来。

// 设置日志对象类的通用属性
  function setCommonProperty() {
    this.happenTime = new Date().getTime(); // 日志发生时间
    this.webMonitorId = WEB_MONITOR_ID;     // 用于区分应用的唯一标识(一个项目对应一个)
    this.simpleUrl =  window.location.href.split('?')[0].replace('#', ''); // 页面的url
    this.customerKey = utils.getCustomerKey(); // 用于区分用户,所对应唯一的标识,清理本地数据后失效
    this.pageKey = utils.getPageKey();  // 用于区分页面,所对应唯一的标识,每个新页面对应一个值
    this.deviceName = DEVICE_INFO.deviceName;
    this.os = DEVICE_INFO.os + (DEVICE_INFO.osVersion ? " " + DEVICE_INFO.osVersion : "");
    this.browserName = DEVICE_INFO.browserName;
    this.browserVersion = DEVICE_INFO.browserVersion;
    // TODO 位置信息, 待处理
    this.monitorIp = "";  // 用户的IP地址
    this.country = "china";  // 用户所在国家
    this.province = "";  // 用户所在省份
    this.city = "";  // 用户所在城市
    // 用户自定义信息, 由开发者主动传入, 便于对线上进行准确定位
    this.userId = USER_INFO.userId;
    this.firstUserParam = USER_INFO.firstUserParam;
    this.secondUserParam = USER_INFO.secondUserParam;
  }

  // JS错误日志,继承于日志基类MonitorBaseInfo
  function JavaScriptErrorInfo(uploadType, errorMsg, errorStack) {
    setCommonProperty.apply(this);
    this.uploadType = uploadType;
    this.errorMessage = encodeURIComponent(errorMsg);
    this.errorStack = errorStack;
    this.browserInfo = BROWSER_INFO;
  }
  JavaScriptErrorInfo.prototype = new MonitorBaseInfo();

  封装了三个JsError对象JavaScriptErrorInfo,用以保存页面中生出的Js错误。个中,setCommonProperty用以设置富有日志对象的通用属性。

  1卡塔 尔(阿拉伯语:قطر‎重写window.onerror 方法,
大家熟习,监察和控制JS错误必然离不开它,有人对她开展了测量检验测量试验介绍深感也是相比用心了

  2卡塔尔重写console.error方法,为啥要重写那个方法,作者不可以预知交给鲜明的答案,即使App第一回向浏览器注入的Js代码报错了,window.onerror是不能够监督到的,所以只可以以此方法来进展捕获,恐怕会有越来越好的办法,待window.onerror成功后,此措施便不再须求用了

  下面是开行JS错误监察和控制代码

/**
   * 页面JS错误监控
   */
  function recordJavaScriptError() {
    // 重写console.error, 可以捕获更全面的报错信息
    var oldError = console.error;
    console.error = function () {
      // arguments的长度为2时,才是error上报的时机
      // if (arguments.length < 2) return;
      var errorMsg = arguments[0] && arguments[0].message;
      var url = WEB_LOCATION;
      var lineNumber = 0;
      var columnNumber = 0;
      var errorObj = arguments[0] && arguments[0].stack;
      if (!errorObj) errorObj = arguments[0];
      // 如果onerror重写成功,就无需在这里进行上报了
      !jsMonitorStarted && siftAndMakeUpMessage(errorMsg, url, lineNumber, columnNumber, errorObj);
      return oldError.apply(console, arguments);
    };
    // 重写 onerror 进行jsError的监听
    window.onerror = function(errorMsg, url, lineNumber, columnNumber, errorObj)
    {
      jsMonitorStarted = true;
      var errorStack = errorObj ? errorObj.stack : null;
      siftAndMakeUpMessage(errorMsg, url, lineNumber, columnNumber, errorStack);
    };

    function siftAndMakeUpMessage(origin_errorMsg, origin_url, origin_lineNumber, origin_columnNumber, origin_errorObj) {
      var errorMsg = origin_errorMsg ? origin_errorMsg : '';
      var errorObj = origin_errorObj ? origin_errorObj : '';
      var errorType = "";
      if (errorMsg) {
        var errorStackStr = JSON.stringify(errorObj)
        errorType = errorStackStr.split(": ")[0].replace('"', "");
      }
      var javaScriptErrorInfo = new JavaScriptErrorInfo(JS_ERROR, errorType + ": " + errorMsg, errorObj);
      javaScriptErrorInfo.handleLogInfo(JS_ERROR, javaScriptErrorInfo);
    };
  };

OK,
错误日志有了,该怎么总括错误率呢?

  JS错误产生率 =
JS错误个数(二次访谈页面中,全体的js错误都算一遍)/PV
(PC,IOS,Android平台同理)

为此大家必要记下页面包车型客车PV记录

 // 用户访问行为日志(PV)
    function CustomerPV(uploadType, loadType, loadTime) {
      setCommonProperty.apply(this);
      this.uploadType = uploadType;
      this.loadType = loadType;  // 用以区分首次加载
      this.loadTime = loadTime; // 加载时间
    }
    CustomerPV.prototype = new MonitorBaseInfo();
    /**
     * 添加一个定时器,进行数据的上传
     * 3秒钟进行一次URL是否变化的检测
     * 15秒钟进行一次数据的检查并上传
     */
    var defaultLocation = window.location.href.split('?')[0].replace('#', '');
    var timeCount = 0;
    setInterval(function () {
      // 如果是单页应用, 只更改url
      var webLocation = window.location.href.split('?')[0].replace('#', '');
      // 如果url变化了, 就把更新的url记录为 defaultLocation, 重新设置pageKey
      if (defaultLocation != webLocation) {
        recordPV();
        defaultLocation = webLocation;
      }
      // 循环5后次进行一次上传
      if (timeCount >= 5) {
        var logInfo = localStorage[ELE_BEHAVIOR] || "" +
          localStorage[JS_ERROR] || "" +
          localStorage[CUSTOMER_PV] || "";
        if (logInfo) {
          utils.ajax("POST", HTTP_UPLOAD_LOG_INFO, {logInfo: logInfo}, function (res) {
            // 上传完成后,清空本地记录
            if (res.code === 200) {
              localStorage[ELE_BEHAVIOR] = "";
              localStorage[JS_ERROR] = "";
              localStorage[CUSTOMER_PV] = "";
            }
          })
        }
        timeCount = 0;
      }
      timeCount ++;
    }, 3000);

  下面的代码笔者用了停车计时器,大概的野趣是3秒进行贰遍U奥迪Q7L变化的自己商议,15秒进行壹次数据的检讨,假设有数据就进展上传,并清空上二遍的数目。为啥用反应计时器呢,因为在单页应用中,路由的切换和地址栏的变化是无可奈何被监督的,小编真正并未有想到特别好的法子来监督,所以用了这种方法,如若有人有更加好的措施,请给自己留言,感谢

 

增加了布尔值,肖似checked,selected

二、JS Error 详细新闻深入深入分析

 

图片 2  

  计算JS
Error的目标,一是为着打探线上项指标健康意况,二是为了深入分析错误,援助大家探求难点之四海,何况化解它。所以,为了追寻并解决难题,我们须求对多少个关键点实行分析。

  ① 
某种错误发生的次数——发生次数跟影响客户是成正比的,
如若发生次数跟影响客户数量都非常高,那么那是一个比较严重的bug,
须求及时解决。 反之,
借使次数过多,影响客户数量超少。表明这种不当只产生在为数不多装置中,优先级相对相当的低,能够择时对此类机型配备实行宽容管理。当然,ip地址访问次数也能表明这些难点

  ② 
页面产生了何等不当——那些有利大家减弱意思的节制,方便大家排查,如:

  图片 3

  ③ 
错误货仓——这一点并非说,是一贯错误最根本的因素。日常景况下,代码都是被减少的,所以自身在后台分析并截收取错代码相近的大器晚成部分代码,进行显示,逐个审查核对错误。 图片 4

  ④ 
设备信息——当错误发生是,解析出客商立时利用设备的浏览器新闻,系统版本,设备机型等等,能够帮大家比异常的快的定势到必要相配的设施,进而提高消释难题的频率。

  ⑤  顾客脚印——笔者个人认为相比有用,不过代价太高。
因为这一个需求记录下客商在页面上的富有行为举止,须求上传比比较多的数额,功能待定。

  图片 5

  到此,已经募集到了JS错误日志的大部音讯了,並且生龙活虎度解析出JS错误的详细音信了。只必要将其上传,入库,再展开解析表现,就足以看看JS错误新闻的预览效果和实际情况。所以,我们再去布置一下后台代码。

 

  上一章:
搭建前端监察和控制系统(生机勃勃卡塔 尔(阿拉伯语:قطر‎Ali云服务器搭建篇

  下一章:
搭建前端监察和控制体系(三卡塔尔NodeJs服务器安插篇

 


 

  

  为了将那么些数量上传到大家的服务器,我们总不可能每一次都用xmlHttpRequest来发送ajax必要吧,

  所以我们必要自身包裹三个简便的Ajax

/**
     *
     * @param method  请求类型(大写)  GET/POST
     * @param url     请求URL
     * @param param   请求参数
     * @param successCallback  成功回调方法
     * @param failCallback   失败回调方法
     */
    this.ajax = function(method, url, param, successCallback, failCallback) {
      var xmlHttp = window.XMLHttpRequest ? new XMLHttpRequest() : new ActiveXObject('Microsoft.XMLHTTP');
      xmlHttp.open(method, url, true);
      xmlHttp.setRequestHeader('Content-Type','application/x-www-form-urlencoded');
      xmlHttp.onreadystatechange = function () {
        if (xmlHttp.readyState == 4 && xmlHttp.status == 200) {
          var res = JSON.parse(xmlHttp.responseText);
          typeof successCallback == 'function' && successCallback(res);
        } else {
          typeof failCallback == 'function' && failCallback();
        }
      };
      xmlHttp.send("data=" + JSON.stringify(param));
    }

 

引号能够总结,然则编码标准的话,不提议,

有能够简单结束符的标签,和完全市略的价签应用。

 

追加标签:

1、结构标签

(1卡塔尔section:独立内容区块,能够用h1~h6结缘大纲,表示文书档案结构,也足以有章节、页眉、页脚或页眉的别样一些;

(2卡塔尔article:特殊独立区块,表示那篇页眉中的主题内容;

(3卡塔 尔(阿拉伯语:قطر‎aside:标签内容之外与标签内容相关的援救消息;

(4卡塔尔header:某些区块的头顶音讯/标题;

(5卡塔尔国hgroup:尾部消息/标题标互补内容;

(6卡塔 尔(阿拉伯语:قطر‎footer:尾部消息;

(7卡塔 尔(阿拉伯语:قطر‎nav:导航条部分新闻;

(8卡塔尔figure:独立的单元,比方某些有图表与内容的音讯块。

 

2、表单标签

(1卡塔尔email:必得输入邮件;

(2卡塔 尔(英语:State of Qatar)url:必得输入url地址;

(3卡塔 尔(英语:State of Qatar)number:必得输入数值;

(4卡塔尔国range:必需输入一定限定内的数值;

(5卡塔 尔(英语:State of Qatar)Date
Pickers:日期选拔器;

    a.date:选取日、月、年

    b.month:选取月、年

    c.week:选用周和年

    d.time:接纳时间(小时和分钟卡塔 尔(英语:State of Qatar)

    e.datetime:选取时间、日、月、年(UTC时间卡塔尔

    f.datetime-local:选择时间、日、月、年(本地时间卡塔尔

(6卡塔 尔(英语:State of Qatar)search:寻找常规的文本域;

发表评论

电子邮件地址不会被公开。 必填项已用*标注