فهرست منبع

TASK #3054 登录时,判断用户浏览器兼容性,不兼容时,提示用户下载纵横Z+或下载Mirosoft Edge

vian 5 سال پیش
والد
کامیت
64e4f2c47b
4فایلهای تغییر یافته به همراه190 افزوده شده و 0 حذف شده
  1. 2 0
      config/gulpConfig.js
  2. 186 0
      public/web/syntax-detection.js
  3. 1 0
      web/building_saas/pm/html/project-management.html
  4. 1 0
      web/users/html/login.html

+ 2 - 0
config/gulpConfig.js

@@ -32,6 +32,7 @@ module.exports = {
     ],
     login_jspaths:[
         'public/web/url_util.js',
+        'public/web/syntax-detection.js',
         'web/users/js/gt.js',
         'web/users/js/login.js'
     ],
@@ -40,6 +41,7 @@ module.exports = {
         'lib/jquery-contextmenu/jquery.contextMenu.css'
     ],
     pm_jspaths:[
+        'public/web/syntax-detection.js',
         'public/web/uuid.js',
         'public/web/date_util.js',
         'public/web/upload_cdn.js',

+ 186 - 0
public/web/syntax-detection.js

@@ -0,0 +1,186 @@
+/** 
+ * 浏览器兼容性,特性检查
+ * 参考列表: http://kangax.github.io/compat-table/es6/
+ * 同内核的不同的浏览器需要处理,比如qq浏览器登陆成功后,ie浏览器登陆页面会自动跳转到项目管理页面。因此项目管理页面也需要检测
+*/
+function checkSyntax() {
+    'use strict';
+    try {
+        // 一些在词法、语法分析阶段就会报错的代码,必须要用window.Function或者eval包裹,否则直接报错且无法被捕获
+        // 不使用eval的原因:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/eval
+        if (typeof window.Function === 'undefined') {
+            return false;
+        }
+
+        // 声明
+        Function('let a = 1;')();
+        Function('const b = 1;')();
+        Function('class A {}')();
+
+        // 模板字符串
+        Function('var a = 1; var str = `${a}`;')();
+
+        // 对象简单表示
+        Function("var foo = 'foo'; var simple = { foo, t() {} };")();
+
+        // 对象属性表示
+        Function("var attr = 'a'; var obj = {[attr]: 1}")();
+
+        // 对象super
+        Function('var proto = { p: 1 }; var obj = { superF() { return super.p } }; Object.setPrototypeOf(obj, proto)')();
+
+        // 对象getter setter
+        Function('var tObj = { get a() {}, set a(v) {} }')();
+
+        // 扩展运算符
+        Function('var obj = { foo: 1 }; var obj1 = { ...obj }; var arr = [1]; var arr1 = [...arr];')();
+
+        // 解构
+        Function('var obj = { foo: 1 }; var { foo } = obj; var arr = [1]; var [one] = arr;')();
+
+        // 可选链 ?. es2020
+        //Function('var obj = { a: { b: 1 } }; obj?.a?.b')();
+
+        // of迭代
+        Function('for (var i of [1]) {}')();
+
+        // 默认参数
+        Function('function defaultParams(a = 1) {}')();
+
+        // rest参数
+        Function('function restParams(...args) {}')();
+
+        // arrow function
+        Function('var arrowF = () => {};')();
+
+        // generator function
+        Function('function* gen() {}')();
+
+        // async function es2017
+        Function('async function tAsync() {}')();
+
+        // Symbol Promise Set Map Proxy Reflect
+        if (typeof Symbol === 'undefined' ||
+            typeof Promise === 'undefined' ||
+            typeof Set === 'undefined' ||
+            typeof Map === 'undefined' ||
+            typeof Proxy === 'undefined' ||
+            typeof Reflect === 'undefined') {
+            return false;
+        }
+        // buffer相关
+        if (typeof ArrayBuffer === 'undefined' ||
+            typeof Uint8Array === 'undefined' ||
+            typeof DataView === 'undefined') {
+            return false;
+        }
+
+        // 部分字符串方法
+        var stringPrototypeFuncs = [
+            'includes',
+            'codePointAt',
+            'normalize',
+            'repeat',
+            //'matchAll', es2020
+            'padStart',
+            'padEnd',
+            //'trimStart', es2019
+            //'trimEnd'
+        ];
+        var stringStaticFuncs = [
+            'fromCodePoint',
+            'raw'
+        ];
+        for (var i = 0; i < stringPrototypeFuncs.length; i++) {
+            var f = stringPrototypeFuncs[i];
+            if (!String.prototype[f]) {
+                throw new SyntaxError('String.prototype ' + f);
+            }
+        }
+        for (var i = 0; i < stringStaticFuncs.length; i++) {
+            var f = stringStaticFuncs[i];
+            if (!String[f]) {
+                throw new SyntaxError('String ' + f);
+            }
+        }
+
+        // 部分数组方法
+        var arrayPrototypeFuncs = [
+            'find',
+            'findIndex',
+            'fill',
+            'keys',
+            'values',
+            'entries',
+            'flat',
+            'flatMap',
+            'includes'
+        ];
+        var arrayStaticFuncs = [
+            'from',
+            'of'
+        ];
+        for (var i = 0; i < arrayPrototypeFuncs.length; i++) {
+            var f = arrayPrototypeFuncs[i];
+            if (!Array.prototype[f]) {
+                throw new SyntaxError('Array.prototyp ' + f);
+            }
+        }
+        for (var i = 0; i < arrayStaticFuncs.length; i++) {
+            var f = arrayStaticFuncs[i];
+            if (!Array[f]) {
+                throw new SyntaxError('Array ' + f);
+            }
+        }
+
+        // 对象部分方法
+        var objectStaticFuncs = [
+            'is',
+            'assign',
+            'getOwnPropertyDescriptors',
+            'setPrototypeOf',
+            'values',
+            'entries',
+            //'fromEntries' // es2020
+        ];
+        for (var i = 0; i < objectStaticFuncs.length; i++) {
+            var f = objectStaticFuncs[i];
+            if (!Object[f]) {
+                throw new SyntaxError('Object ' + f);
+            }
+        }
+
+    } catch (err) {
+        console.log(err);
+        return false;
+    }
+    return true;
+}
+
+function showBrowserTip() {
+    var html = '<div class="modal fade" id="browser" data-backdrop="static">' +
+        '<div class="modal-dialog modal-lg" role="document">' +
+        '<div class="modal-content">' +
+            '<div class="modal-body">' +
+                '<h5>浏览器版本过低,可能会有安全风险;</h5>' +
+                '<h5>请更新 「浏览器」 或者 使用 「纵横Z+造价工作平台」 登录。</h5>' +
+                '<div class="row my-4">' +
+                    '<div class="col-6">' +
+                        '<div class="text-center"><a href="https://www.microsoft.com/zh-cn/edge" class="btn btn-primary" target="_blank">下载 Microsoft Edge</a></div>' +
+                    '</div>' +
+                    '<div class="col-6">' +
+                        '<div class="text-center"><a href="https://smartcost.com.cn/downloadzplus" class="btn btn-primary" target="_blank">下载 纵横Z+造价工作平台</a></div>' +
+                    '</div></div></div></div></div></div>';
+    $('body').append(html);
+    $('#browser').modal('show');
+}
+
+$(document).ready(function () {
+    // 浏览器兼容性
+    var isCompat = checkSyntax();
+    if (!isCompat) {
+        $('#inputEmail').blur();
+        showBrowserTip();
+        return false;
+    }
+});

+ 1 - 0
web/building_saas/pm/html/project-management.html

@@ -930,6 +930,7 @@
     console.log(billValuation);
 </script>
 <!-- inject:js -->
+<script type="text/javascript" src="/public/web/syntax-detection.js"></script>
 <script src="/web/building_saas/js/global.js"></script>
 <script src="/public/web/uuid.js"></script>
 <script src="/public/web/date_util.js"></script>

+ 1 - 0
web/users/html/login.html

@@ -180,6 +180,7 @@
     <script src="/public/web/url_util.js"></script>
     <script src="/lib/popper/popper.min.js"></script>
     <script src="/lib/bootstrap/bootstrap.min.js"></script>
+    <script type="text/javascript" src="/public/web/syntax-detection.js"></script>
     <script src="/web/building_saas/js/global.js"></script>
     <script type="text/javascript" src="/web/users/js/gt.js"></script>
     <script type="text/javascript" src="/web/users/js/login.js"></script>