js识别终端

本文介绍了一种通过解析User-Agent字符串来识别浏览器类型及其版本的方法。该方法能够准确地识别包括IE、Chrome、Firefox等在内的主流浏览器,并能进一步区分移动设备上的浏览器特性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

识别终端

(function (B){
    /*global process*/

    var win = B.Env.host,
        doc = win.document,
        navigator = win.navigator,
        ua = navigator && navigator.userAgent || '';

    function numberify(s){
        var c = 0;
        // convert '1.2.3.4' to 1.234
        return parseFloat(s.replace(/\./g, function (){
            return (c++ === 0) ? '.' : '';
        }));
    }

    function setTridentVersion(ua, UA){
        var core, m;
        UA[core = 'trident'] = 0.1; // Trident detected, look for revision

        // Get the Trident's accurate version
        if((m = ua.match(/Trident\/([\d.]*)/)) && m[1]){
            UA[core] = numberify(m[1]);
        }

        UA.core = core;
    }

    function getIEVersion(ua){
        var m, v;
        if((m = ua.match(/MSIE ([^;]*)|Trident.*; rv(?:\s|:)?([0-9.]+)/)) &&
            (v = (m[1] || m[2]))){
            return numberify(v);
        }
        return 0;
    }

    function getDescriptorFromUserAgent(ua){
        var EMPTY = '',
            os,
            core = EMPTY,
            shell = EMPTY, m,
            IE_DETECT_RANGE = [6, 9],
            ieVersion,
            v,
            end,
            VERSION_PLACEHOLDER = '{{version}}',
            IE_DETECT_TPL = '<!--[if IE ' + VERSION_PLACEHOLDER + ']><' + 's></s><![endif]-->',
            div = doc && doc.createElement('div'),
            s = [];
        /**
         * UA
         * @class B.UA
         * @singleton
         */
        var UA = {
            /**
             * webkit version
             * @type undefined|Number
             * @member BAI.UA
             */
            webkit: undefined,
            /**
             * trident version
             * @type undefined|Number
             * @member BAI.UA
             */
            trident: undefined,
            /**
             * gecko version
             * @type undefined|Number
             * @member BAI.UA
             */
            gecko: undefined,
            /**
             * presto version
             * @type undefined|Number
             * @member BAI.UA
             */
            presto: undefined,
            /**
             * chrome version
             * @type undefined|Number
             * @member BAI.UA
             */
            chrome: undefined,
            /**
             * safari version
             * @type undefined|Number
             * @member BAI.UA
             */
            safari: undefined,
            /**
             * firefox version
             * @type undefined|Number
             * @member BAI.UA
             */
            firefox: undefined,
            /**
             * ie version
             * @type undefined|Number
             * @member BAI.UA
             */
            ie: undefined,
            /**
             * ie document mode
             * @type undefined|Number
             * @member BAI.UA
             */
            ieMode: undefined,
            /**
             * opera version
             * @type undefined|Number
             * @member BAI.UA
             */
            opera: undefined,
            /**
             * mobile browser. apple, android.
             * @type String
             * @member BAI.UA
             */
            mobile: undefined,
            /**
             * browser render engine name. webkit, trident
             * @type String
             * @member BAI.UA
             */
            core: undefined,
            /**
             * browser shell name. ie, chrome, firefox
             * @type String
             * @member BAI.UA
             */
            shell: undefined,

            /**
             * PhantomJS version number
             * @type undefined|Number
             * @member BAI.UA
             */
            phantomjs: undefined,

            /**
             * operating system. android, ios, linux, windows
             * @type string
             * @member BAI.UA
             */
            os: undefined,

            /**
             * ipad ios version
             * @type Number
             * @member BAI.UA
             */
            ipad: undefined,
            /**
             * iphone ios version
             * @type Number
             * @member BAI.UA
             */
            iphone: undefined,
            /**
             * ipod ios
             * @type Number
             * @member BAI.UA
             */
            ipod: undefined,
            /**
             * ios version
             * @type Number
             * @member BAI.UA
             */
            ios: undefined,

            /**
             * android version
             * @type Number
             * @member BAI.UA
             */
            android: undefined,

            /**
             * nodejs version
             * @type Number
             * @member BAI.UA
             */
            nodejs: undefined
        };

        // ejecta
        if(div && div.getElementsByTagName){
            // try to use IE-Conditional-Comment detect IE more accurately
            // IE10 doesn't support this method, @ref: http://blogs.msdn.com/b/ie/archive/2011/07/06/html5-parsing-in-ie10.aspx
            div.innerHTML = IE_DETECT_TPL.replace(VERSION_PLACEHOLDER, '');
            s = div.getElementsByTagName('s');
        }

        if(s.length > 0){

            setTridentVersion(ua, UA);

            // Detect the accurate version
            // 注意:
            //  UA.shell = ie, 表示外壳是 ie
            //  但 UA.ie = 7, 并不代表外壳是 ie7, 还有可能是 ie8 的兼容模式
            //  对于 ie8 的兼容模式,还要通过 documentMode 去判断。但此处不能让 UA.ie = 8, 否则
            //  很多脚本判断会失误。因为 ie8 的兼容模式表现行为和 ie7 相同,而不是和 ie8 相同
            for (v = IE_DETECT_RANGE[0], end = IE_DETECT_RANGE[1]; v <= end; v++) {
                div.innerHTML = IE_DETECT_TPL.replace(VERSION_PLACEHOLDER, v);
                if(s.length > 0){
                    UA[shell = 'ie'] = v;
                    break;
                }
            }

            // win8 embed app
            if(!UA.ie && (ieVersion = getIEVersion(ua))){
                UA[shell = 'ie'] = ieVersion;
            }

        } else {
            // WebKit
            if((m = ua.match(/AppleWebKit\/([\d.]*)/)) && m[1]){
                UA[core = 'webkit'] = numberify(m[1]);

                if((m = ua.match(/OPR\/(\d+\.\d+)/)) && m[1]){
                    UA[shell = 'opera'] = numberify(m[1]);
                }
                // Chrome
                else if((m = ua.match(/Chrome\/([\d.]*)/)) && m[1]){
                    UA[shell = 'chrome'] = numberify(m[1]);
                }
                // Safari
                else if((m = ua.match(/\/([\d.]*) Safari/)) && m[1]){
                    UA[shell = 'safari'] = numberify(m[1]);
                }

                // Apple Mobile
                if(/ Mobile\//.test(ua) && ua.match(/iPad|iPod|iPhone/)){
                    UA.mobile = 'apple'; // iPad, iPhone or iPod Touch

                    m = ua.match(/OS ([^\s]*)/);
                    if(m && m[1]){
                        UA.ios = numberify(m[1].replace('_', '.'));
                    }
                    os = 'ios';
                    m = ua.match(/iPad|iPod|iPhone/);
                    if(m && m[0]){
                        UA[m[0].toLowerCase()] = UA.ios;
                    }
                } else if(/ Android/i.test(ua)){
                    if(/Mobile/.test(ua)){
                        os = UA.mobile = 'android';
                    }
                    m = ua.match(/Android ([^\s]*);/);
                    if(m && m[1]){
                        UA.android = numberify(m[1]);
                    }
                }
                // Other WebKit Mobile Browsers
                else if((m = ua.match(/NokiaN[^\/]*|Android \d\.\d|webOS\/\d\.\d/))){
                    UA.mobile = m[0].toLowerCase(); // Nokia N-series, Android, webOS, ex: NokiaN95
                }

                if((m = ua.match(/PhantomJS\/([^\s]*)/)) && m[1]){
                    UA.phantomjs = numberify(m[1]);
                }
            }
            // NOT WebKit
            else {
                // Presto
                // ref: http://www.useragentstring.com/pages/useragentstring.php
                if((m = ua.match(/Presto\/([\d.]*)/)) && m[1]){
                    UA[core = 'presto'] = numberify(m[1]);

                    // Opera
                    if((m = ua.match(/Opera\/([\d.]*)/)) && m[1]){
                        UA[shell = 'opera'] = numberify(m[1]); // Opera detected, look for revision

                        if((m = ua.match(/Opera\/.* Version\/([\d.]*)/)) && m[1]){
                            UA[shell] = numberify(m[1]);
                        }

                        // Opera Mini
                        if((m = ua.match(/Opera Mini[^;]*/)) && m){
                            UA.mobile = m[0].toLowerCase(); // ex: Opera Mini/2.0.4509/1316
                        }
                        // Opera Mobile
                        // ex: Opera/9.80 (Windows NT 6.1; Opera Mobi/49; U; en) Presto/2.4.18 Version/10.00
                        // issue: 由于 Opera Mobile 有 Version/ 字段,可能会与 Opera 混淆,同时对于 Opera Mobile 的版本号也比较混乱
                        else if((m = ua.match(/Opera Mobi[^;]*/)) && m){
                            UA.mobile = m[0];
                        }
                    }

                    // NOT WebKit or Presto
                } else {
                    // MSIE
                    // 由于最开始已经使用了 IE 条件注释判断,因此落到这里的唯一可能性只有 IE10+
                    // and analysis tools in nodejs
                    if((ieVersion = getIEVersion(ua))){
                        UA[shell = 'ie'] = ieVersion;
                        setTridentVersion(ua, UA);
                        // NOT WebKit, Presto or IE
                    } else {
                        // Gecko
                        if((m = ua.match(/Gecko/))){
                            UA[core = 'gecko'] = 0.1; // Gecko detected, look for revision
                            if((m = ua.match(/rv:([\d.]*)/)) && m[1]){
                                UA[core] = numberify(m[1]);
                                if(/Mobile|Tablet/.test(ua)){
                                    UA.mobile = 'firefox';
                                }
                            }
                            // Firefox
                            if((m = ua.match(/Firefox\/([\d.]*)/)) && m[1]){
                                UA[shell = 'firefox'] = numberify(m[1]);
                            }
                        }
                    }
                }
            }
        }

        if(!os){
            if((/windows|win32/i).test(ua)){
                os = 'windows';
            } else if((/macintosh|mac_powerpc/i).test(ua)){
                os = 'macintosh';
            } else if((/linux/i).test(ua)){
                os = 'linux';
            } else if((/rhino/i).test(ua)){
                os = 'rhino';
            }
        }

        UA.os = os;
        UA.core = UA.core || core;
        UA.shell = shell;
        UA.ieMode = UA.ie && doc.documentMode || UA.ie;

        return UA;
    }

    var UA = B.UA = getDescriptorFromUserAgent(ua);

    // nodejs
    if(typeof process === 'object'){
        var versions, nodeVersion;

        if((versions = process.versions) && (nodeVersion = versions.node)){
            UA.os = process.platform;
            UA.nodejs = numberify(nodeVersion);
        }
    }

    // use by analysis tools in nodejs
    UA.getDescriptorFromUserAgent = getDescriptorFromUserAgent;

    //设置html的Css
//    var browsers = [
//            // browser core type
//            'webkit',
//            'trident',
//            'gecko',
//            'presto',
//            // browser type
//            'chrome',
//            'safari',
//            'firefox',
//            'ie',
//            'opera'
//        ],
//        documentElement = doc && doc.documentElement,
//        className = '';
//    if (documentElement) {
//        B.each(browsers, function (key) {
//            var v = UA[key];
//            if (v) {
//                className += ' ks-' + key + (parseInt(v) + '');
//                className += ' ks-' + key;
//            }
//        });
//        if (B.trim(className)) {
//            documentElement.className = B.trim(documentElement.className + className);
//        }
//    }
})(B);
<think>好的,用户现在遇到了WebStorm终端无法识别npm的问题。首先,我需要回想一下之前用户的问题历史。之前他在安装Node.js 14.15.0时遇到了npm安装错误,可能是网络或权限问题。现在的新问题是WebStorm终端无法识别npm,这可能和之前的问题有关,或者是一个新的环境配置问题。 首先,我要考虑可能的原因。WebStorm终端无法识别npm通常有几个常见原因:Node.js未正确安装,环境变量未配置,或者WebStorm的终端配置有问题。此外,用户可能使用了nvm来管理Node版本,这可能导致路径问题。 接下来,我需要分步骤思考解决方案。第一步,检查Node.js和npm的安装是否正确。用户之前用nvm安装,可能需要确认安装是否完成,是否存在之前的错误残留。如果之前安装失败,npm可能未被正确安装,导致命令不可用。 第二步,检查环境变量。特别是系统PATH是否包含Node.js和npm的路径。如果用户使用nvm,可能需要确保nvm的环境变量正确设置。有时候,终端需要重启或重新加载环境变量才能生效。 第三步,检查WebStorm的终端配置。WebStorm默认可能使用自己的终端设置,比如PowerShell或CMD,可能没有正确加载用户的环境变量。需要确认终端是否以管理员权限运行,或者是否继承系统环境变量。 第四步,可能的权限问题。如果用户安装在系统目录或受保护的位置,可能需要管理员权限才能访问。或者,杀毒软件可能阻止了npm的执行。 另外,用户之前遇到的问题可能有残留影响。比如,安装失败后,nvm可能没有正确配置路径,或者存在损坏的文件。需要建议用户彻底卸载并重新安装Node.js和npm,或者尝试其他版本。 还需要考虑用户是否在项目中使用正确的Node版本。如果项目有.nvmrc文件,但nvm没有自动切换版本,可能导致npm命令不可用。这时候需要手动切换版本。 可能还要检查WebStorm的Node.js插件是否启用,或者是否需要重新配置Node解释器路径。在WebStorm的设置中,可以指定Node.js的路径,如果路径不正确,终端可能无法识别npm。 最后,建议用户提供更多错误信息,比如具体的错误提示,或者尝试在系统终端中运行npm命令,以确定是否是WebStorm特有的问题,还是系统环境的问题。这有助于缩小问题范围。 总结一下,可能的解决步骤是:确认Node.js和npm安装正确,检查环境变量,调整WebStorm终端设置,检查权限问题,重新安装或切换Node版本,配置WebStorm的Node解释器路径。需要一步步引导用户排查,确保每个环节都检查到。</think>以下是在 WebStorm 中终端无法识别 npm 的排查指南,按优先级排序解决方案: --- ### 一、验证基础环境 (必做) 1. **检查系统终端是否正常** 打开系统自带的 **cmd** 或 **PowerShell**,执行: ```bash where npm # Windows which npm # macOS/Linux ``` - ✅ 正常:显示类似 `C:\Program Files\nodejs\npm.cmd` 的路径 - ❌ 无输出:说明系统环境变量未配置 2. **修复环境变量** - 找到 Node.js 安装路径(默认:`C:\Program Files\nodejs\`) - 将以下路径加入系统环境变量 `PATH`: ```text C:\Program Files\nodejs\ %APPDATA%\npm ``` --- ### 二、WebStorm 配置修正 #### 场景 1:终端类型错误 1. 进入 **Settings > Tools > Terminal** 2. 检查 **Shell path** 设置: ```text cmd.exe → Windows 推荐 powershell.exe ``` ![WebStorm终端设置示意图](https://resources.jetbrains.com/help/img/idea/2023.3/ps_settings_tools_terminal.png) #### 场景 2:Node.js 解释器未指定 1. 进入 **Settings > Languages & Frameworks > Node.js** 2. 确认 **Node interpreter** 路径正确(如 `C:\Program Files\nodejs\node.exe`) --- ### 三、权限冲突处理 #### 案例 1:杀毒软件拦截 - 临时关闭 **Windows Defender** 或第三方杀毒软件 - 在 WebStorm 中尝试执行: ```bash npm -v ``` #### 案例 2:系统权限不足 - 右键 WebStorm 图标 → **以管理员身份运行** - 在终端执行: ```bash npm cache clean --force ``` --- ### 四、终极解决方案 若以上均无效,执行 **完整重装流程**: 1. 卸载 Node.js(通过控制面板) 2. 删除残留文件: ```text C:\Program Files\nodejs\ C:\Users\你的用户名\AppData\Roaming\npm ``` 3. 重新安装 **Node.js LTS 版本**([官网下载](https://nodejs.org/)) 4. 重启 WebStorm --- ### 常见错误特征对照表 | 错误现象 | 解决方案 | |---------|----------| | `'npm' 不是内部或外部命令` | 环境变量配置 + 重装 Node.js | | 终端识别但 WebStorm 不识别 | 检查 WebStorm 的 Node.js 插件状态 | | 仅特定项目报错 | 检查项目根目录的 `.npmrc` 文件是否存在冲突配置 | --- ### 扩展建议 - 使用 **nvm-windows** 管理多版本 Node.js([GitHub 地址](https://github.com/coreybutler/nvm-windows)) - 在 WebStorm 中直接调用系统终端: ```text Settings → Tools → Terminal → Application Settings → Shell path → 改为 cmd.exe ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值