如何使用Angular检测浏览器?

69

我需要使用Angular(TypeScript)来检测浏览器是否为IE或Edge。这是否可能?如果可能,该如何实现?


1
请看 https://www.npmjs.com/package/ngx-device-detector - tmorell
11个回答

82

我之前使用过这个,效果很好。

const isIEOrEdge = /msie\s|trident\/|edge\//i.test(window.navigator.userAgent)

@Maddy 你可以在组件、服务等中使用它。 - argoo
2
我认为你不需要在这里使用 letconst 应该更合适。 - Okonomiyaki3000
1
很好,它也适用于Edge2(结果为负,正如预期),谢谢。 - Václav Švára
1
为了检测FF,我也使用了 -> isIEOrEdgeOrFF: boolean = /msie\s|Firefox|trident/|edge//i.test(window.navigator.userAgent); - Hamid Reza
此内容不再有效。edge返回的用户代理值为“Mozilla/5.0(Windows NT 10.0; Win64; x64)AppleWebKit /537.36 (KHTML, like Gecko)Chrome/96.0.4664.55 Safari/537.36 Edg/96.0.1054.41”。 - James Parker
显示剩余2条评论

35
请使用以下代码:

// Opera 8.0+
    var isOpera = (!!window.opr && !!opr.addons) || !!window.opera || navigator.userAgent.indexOf(' OPR/') >= 0;

    // Firefox 1.0+
    var isFirefox = typeof InstallTrigger !== 'undefined';

    // Safari 3.0+ "[object HTMLElementConstructor]" 
    var isSafari = /constructor/i.test(window.HTMLElement) || (function (p) { return p.toString() === "[object SafariRemoteNotification]"; })(!window['safari'] || safari.pushNotification);

    // Internet Explorer 6-11
    var isIE = /*@cc_on!@*/false || !!document.documentMode;

    // Edge 20+
    var isEdge = !isIE && !!window.StyleMedia;

    // Chrome 1+
    //var isChrome = !!window.chrome && !!window.chrome.webstore;
    // If isChrome is undefined, then use:
    var isChrome = !!window.chrome && (!!window.chrome.webstore || !!window.chrome.runtime);
    // Blink engine detection
    var isBlink = (isChrome || isOpera) && !!window.CSS;

    var output = 'Detecting browsers by ducktyping:<hr>';
    output += 'isFirefox: ' + isFirefox + '<br>';
    output += 'isChrome: ' + isChrome + '<br>';
    output += 'isSafari: ' + isSafari + '<br>';
    output += 'isOpera: ' + isOpera + '<br>';
    output += 'isIE: ' + isIE + '<br>';
    output += 'isEdge: ' + isEdge + '<br>';
    output += 'isBlink: ' + isBlink + '<br>';
    document.body.innerHTML = output;


2
@Liutas Angular使用TypeScript,它是JavaScript的超集。当然可以。 - Roland Rácz
5
Angular CLI在使用window、chrome时会抛出错误,但是使用!!window['chrome']&& !!window['chrome']['webstore']可以正常工作。 - Cristian Sepulveda
2
这段代码现在在所有浏览器中都显示为false。我是从Win7上的Chrome中启动它的。 - grreeenn
你尝试过使用 !!window['chrome']&& !!window['chrome']['webstore'] 吗? - I. Ahmed
最近版本中chrome.webstore未定义。请改用!!window.chrome && (!!window.chrome.webstore || !!window.chrome.runtime); - devqon
显示剩余4条评论

29

针对仍在查找此线程的人:

如果您使用的是 Angular 10 或更高版本,建议使用 PlatformModule,该模块已在 Angular Material CDK 的版本 10 中添加。

https://material.angular.io/cdk/platform/api


1
这个不太好用。我目前正在Edge中查看返回的结果,它显示“EDGE:false”。 - James Parker
4
那是因为你正在使用基于Chromium的新Edge浏览器。如果你检查Blink,可能会返回true。Blink是浏览器排版引擎,也是Chromium的一部分,因此无论是在Edge还是Chrome中都是如此。我相信EDGE: false是在寻找旧版的Microsoft Edge浏览器,而那个浏览器不是基于Chromium的。 - Scopperloit

20

这对我有用:

  public getBrowserName() {
    const agent = window.navigator.userAgent.toLowerCase()
    switch (true) {
      case agent.indexOf('edge') > -1:
        return 'edge';
      case agent.indexOf('opr') > -1 && !!(<any>window).opr:
        return 'opera';
      case agent.indexOf('chrome') > -1 && !!(<any>window).chrome:
        return 'chrome';
      case agent.indexOf('trident') > -1:
        return 'ie';
      case agent.indexOf('firefox') > -1:
        return 'firefox';
      case agent.indexOf('safari') > -1:
        return 'safari';
      default:
        return 'other';
    }
}

在调用getBrowserName()之后,您可以将返回值与==='edge'进行比较,以查看您是否在使用 Edge 浏览器。


1
当我在Chrome上运行您的代码时,它会打印出以下内容: const agent = window.navigator.userAgent.toLocaleLowerCase(); console.log('agent' + agent);agentmozilla/5.0 (windows nt 10.0; win64; x64) applewebkit/537.36 (khtml, like gecko) chrome/70.0.3538.102 safari/537.36 而在Edge上: agentmozilla/5.0 (windows nt 10.0; win64; x64) applewebkit/537.36 (khtml, like gecko) chrome/70.0.3538.102 safari/537.36 edge/18.18362(agent.indexOf('safari') > -1 或者 (agent.indexOf('chrome') > -1 将在任何浏览器上始终返回true。请问您能否澄清一下这个问题? - Malhaar Punjabi
这不会在 iPhone 12 上返回 Chrome,即使使用 Chrome... - Stefan Walther
添加 case agent.indexOf('edg') > -1: return 'edge'; - James Parker
请注意:此代码片段严重依赖于浏览器使用度量标准。如果您只测试 agent.indexOf('safari') > -1,则几乎每个现代浏览器都会返回 true,因为大多数浏览器会重复其用户代理字符串的某些部分,因此此检测依赖于进行评估的顺序。 - agbb

8

对于Angular用户,您可以使用此模块npm install ngx-device-detector --save

以上的答案对我都不起作用。


模块总是增加捆绑包大小,所以我认为为什么我们要使用第三方模块,而我们可以编写自己的代码,这是一个不好的方法。 - Nagender Pratap Chauhan
@nagenderpratapchauhan 是的,这是真的。对我来说,使用实用程序是一个问题,因为我不能花4-5个小时来编写和测试我的自定义浏览器检测器。我相信这个模块也只有所需的代码和很多额外的代码,因为这个模块执行了非常特定的功能。 - penduDev
从安装到成功部署只用了5分钟。deviceInfo: {"userAgent":"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36","os":"Windows","browser":"Chrome","device":"Unknown","os_version":"windows-10","browser_version":"75.0.3770.100"}。而且,这是Angular的方式! - BobC
1
这个在一年的大部分时间里都是有效的,但在某个时候(可能是更新到Angular 8时)它停止工作了。请注意,在开发中它可以完美运行(ng serve),但在生产构建中失败了。它只是返回:browser = ""。 - egalot

4

浏览器的userAgent会随着时间的推移而不同和发展。与其手动解析userAgent,不如考虑使用一个维护良好的库来确保未来支持。最流行的选项有:

1. UAParser.js

这个优秀的库将从User-Agent数据中分析客户端浏览器、引擎、操作系统、CPU和设备类型/型号,并具有相对较小的占用空间。它得到了高度的维护和极大的普及(目前每周下载量为7.3M)。使用方法很简单:

import { UAParser } from 'ua-parser-js'; 

const parser = new UAParser();
const result = parser.getResult();

const isEdge = result.browser == 'Edge';

2. Angular Material

在Angular Material V6.4.7中引入了"Platform"检测模块:

平台:通过比较userAgent字符串和检查特定于浏览器的全局属性来检测当前平台的服务。

关于EDGE的重要说明:自版本79起,EDGE使用Blink浏览器引擎,因此此选项仅适用于旧版EDGE。

导入Platform服务并直接检查EDGE(或任何其他浏览器/操作系统):

import { Platform } from '@angular/cdk/platform';

@Injectable()
export class AppService {
    
    isEdge: boolean;

    constructor(private platform: Platform) {
        this.isEdge = this.platform.EDGE; // or IOS, SAFARI, ANDROID, etc.
    }
}

1
这应该是正确的答案,解析userAgent字符串只会引起随着时间推移而出现的维护问题。 - RocketMan
1
平台表现不太好 - 在Edge和平台上进行了测试。EDGE返回为false。但UAParser表现良好! - Karen
非常感谢,@Karen。这是非常重要的知识。 - Shaya
1
本文非常清楚地解释了不同的平台布尔值:https://www.decodedfrontend.io/detect-browser-and-os-with-angular-cdk-platform-module/ - Stephanie
嗨@Stephanie,谢谢。引用这篇文章:“注意!自版本79起,EDGE使用Blink浏览器引擎,因此此选项仅适用于旧版EDGE。” - Shaya

3
如果您愿意使用外部模块,您可以使用ngx-device-detector。
$ npm install ngx-device-detector --save

用法:
  import { NgModule } from '@angular/core';
  import { DeviceDetectorModule } from 'ngx-device-detector';
  ...
  @NgModule({
    declarations: [
      ...
      LoginComponent,
      SignupComponent
      ...
    ],
    imports: [
      CommonModule,
      FormsModule,
      DeviceDetectorModule.forRoot()
    ],
    providers:[
      AuthService
    ]
    ...
  })

在您想要使用设备服务的组件中。
 import { Component } from '@angular/core';
  ...
  import { DeviceDetectorService } from 'ngx-device-detector';
  ...
  @Component({
    selector: 'home',  // <home></home>
    styleUrls: [ './home.component.scss' ],
    templateUrl: './home.component.html',
    ...
  })

  export class HomeComponent {
    deviceInfo = null;
    ...
    constructor(..., private http: Http, private deviceService: DeviceDetectorService) {
      this.epicFunction();
    }
    ...
    epicFunction() {
      console.log('hello `Home` component');
      this.deviceInfo = this.deviceService.getDeviceInfo();
      const isMobile = this.deviceService.isMobile();
      const isTablet = this.deviceService.isTablet();
      const isDesktopDevice = this.deviceService.isDesktop();
      console.log(this.deviceInfo);
      console.log(isMobile);  // returns if the device is a mobile device (android / iPhone / windows-phone etc)
      console.log(isTablet);  // returns if the device us a tablet (iPad etc)
      console.log(isDesktopDevice); // returns if the app is running on a Desktop browser.
    }
    ...
  }

设备服务 包含以下属性:
  1. 浏览器
  2. 操作系统
  3. 设备
  4. 用户代理
  5. 操作系统版本
辅助方法:
isMobile():返回设备是否为移动设备(Android / iPhone / Windows Phone等)。
isTablet():返回设备是否为平板电脑(iPad等)。
isDesktop():返回应用程序是否在桌面浏览器上运行。
这是文档链接:https://koderlabs.github.io/ngx-device-detector/index.html

1

您可以使用正则表达式和用户代理来检测IE浏览器。

 private isIE() {
    const match = navigator.userAgent.search(/(?:Edge|MSIE|Trident\/.*; rv:)/);
    let isIE = false;

    if (match !== -1) {
        isIE = true;
    }

    return isIE;
}

但是,推荐使用特性检测而不是浏览器检测。您可以使用现代化的库来完成这项工作 https://modernizr.com


1
您可以使用以下代码获取浏览器名称:

let match = navigator.userAgent.search(/(?:Edge|MSIE|Trident\/.*; rv:)/);
let isIE = false;

if (match !== -1) {
    isIE = true;
}
console.log(isIE,'isIE');


在正则表达式搜索中添加“edg”。 - James Parker

1
要检测浏览器是否基于Chromium,请使用以下代码:
const isChromiumBased =
  !!window["chrome"] &&
  (!!window["chrome"]["webstore"] || !!window["chrome"]["runtime"]);

!!(window.chrome && (window.chrome.webstore || window.chrome.runtime)) - MrHIDEn
我尝试了这个......现在,在我的部署版本的Angular应用中,这行代码运行得非常完美,但是(就在旁边的Chrome标签页中)相同的代码行在我的本地主机版本中却说它不是Chrome。啊啊啊啊! - Mike Gledhill

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接