如何在Angular2中检查用户是否有互联网连接?

时间:2016-09-19 10:44:12

标签: http angular

在API点击时我如何检查Angular2中的互联网连接,每当我的应用程序API被命中到服务器时有时用户是 离线(我的意思是没有互联网连接)所以我如何检查互联网连接?是否有一些特殊的互联网连接状态代码? 或者是其他东西 ?

PS: - 我在angularJs中找到navigator.onLine但似乎没有在angular2中工作。

更新

正如sudheer在使用angular2时在navigator.onLine下面的回答中建议但仍然无法正常工作的原因? working example here

9 个答案:

答案 0 :(得分:34)

(2018)为rxjs6更新了代码

完全适用于angular2。显然它与angularJS不同,因为$ scope和$ apply都不再存在。不过,RxJS让这很简单!在Chrome 53上测试:

模板:

<p>{{online$ | async}}</p>

成分:

import { Observable, fromEvent, merge, of } from 'rxjs';
import { mapTo } from 'rxjs/operators';

@Component({ /* ... */ })
export class MyComponent {
  online$: Observable<boolean>;

  constructor() {
    this.online$ = merge(
      of(navigator.onLine),
      fromEvent(window, 'online').pipe(mapTo(true)),
      fromEvent(window, 'offline').pipe(mapTo(false))
    );
  }
}

考虑“离线”对您的用例意味着什么!

未插入的以太网电缆和3KB / s的EDGE连接可能会对您的应用产生同样的影响,尽管后者意味着您技术上没有离线

从程序员的角度来看,无线连接的信号非常差,实际上要比真正断开连接更糟糕,因为它更难以检测到!

以上代码返回false值意味着您完全脱机,因为已断开连接。返回true并不一定表示存在实际可用的连接。

答案 1 :(得分:14)

起初,j2L4e的答案对我不起作用(在Chrome中测试)。我通过在ngIf的括号中包围我的bool来略微调整,这最终起作用了。

<md-icon class="connected" mdTooltip="No Connection" *ngIf="!(isConnected | async)">signal_wifi_off</md-icon>

import { Component, OnInit } from '@angular/core';
import { Observable } from 'rxjs/Observable';
import { Subscription } from 'rxjs/Subscription';
import 'rxjs/Rx';

@Component({
  selector: 'toolbar',
  templateUrl: './toolbar.component.html',
  styleUrls: ['./toolbar.component.css']
})
export class ToolbarComponent implements OnInit {
  isConnected: Observable<boolean>;

  constructor() {
    this.isConnected = Observable.merge(
      Observable.of(navigator.onLine),
      Observable.fromEvent(window, 'online').map(() => true),
      Observable.fromEvent(window, 'offline').map(() => false));
  }

  ngOnInit() {

  }
}

答案 2 :(得分:9)

因为我检查过导航器是像窗口一样的全局对象。你可以在angular2中使用它,它对我来说很好。

PATH='/sdks/android-sdk-macosx/tools:/sdks/android-sdk-macosx/platform-tools:/Library/Java/JavaVirtualMachines/jdk1.8.0_51.jdk/Contents/Home/bin:/Applications/Genymotion.app/Contents/MacOS'

答案 3 :(得分:5)

使用 Angular 6 + Rxjs 6 + ,您可以通过以下方式执行此操作:

import { Observable, fromEvent, merge, of } from 'rxjs';
import { mapTo } from 'rxjs/operators';

online$: Observable<boolean>;

constructor() {
  this.online$ = merge(
    of(navigator.onLine),
    fromEvent(window, 'online').pipe(mapTo(true)),
    fromEvent(window, 'offline').pipe(mapTo(false))
  )
}

这是demo(开发工具中的切换网络)

答案 4 :(得分:2)

对于Angular 9-一个非常简单的解决方案,易于使用(感谢thisthis解决方案):

1)创建新组件:

ng g c NoConnection

no-connection.component.ts

import { Component, OnInit } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser'
import { HttpClient }    from '@angular/common/http';

@Component({
  selector: 'app-no-connection',
  templateUrl: './no-connection.component.html',
  styleUrls: ['./no-connection.component.css']
})
export class NoConnectionComponent implements OnInit {

  isConnectionAvailable: boolean = navigator.onLine; 

  constructor(private httpClient: HttpClient) { 
      window.addEventListener('online', () => {
        this.isConnectionAvailable = true
    });

    window.addEventListener('offline', () => {
        this.isConnectionAvailable = false
    });
  }

  ngOnInit(): void {
  }

}

no-connection.component.html (所需的自定义页面)

<div>

    <p style.color = "{{ isConnectionAvailable  ? 'green' : 'red'}}"> {{ isConnectionAvailable  ? 'Online' : 'Offline'}} </p>  

    <!-- https://stackoverflow.com/questions/13350663/greyed-out-waiting-page-in-javascript#answer-13350908 -->
    <div id="blackout" class="noselect" style.display = "{{isConnectionAvailable ? 'none' : 'block'}}">
        <br><br><br><br><br>
        <p>No Internet connection!</p>
        <br>
    </div>

</div>

no-connection.component.css

#blackout {
    width:100%;
    height:100%; /* make sure you have set parents to a height of 100% too*/
    position: absolute;
    left:0; top:0;
    z-index:10; /*just to make sure its on top*/

    opacity: 0.5; 
    background-color:#333; 
    text-align: center;

    font-size:25px; 
    color: white;
}

.noselect {
  -webkit-touch-callout: none; /* iOS Safari */
    -webkit-user-select: none; /* Safari */
     -khtml-user-select: none; /* Konqueror HTML */
       -moz-user-select: none; /* Old versions of Firefox */
        -ms-user-select: none; /* Internet Explorer/Edge */
            user-select: none; /* Non-prefixed version, currently
                                  supported by Chrome, Opera and Firefox */                               
}

2)可以在任何地方使用它-在我的情况下,最好的地方-是根组件:

app.component.html

<div>

    <app-no-connection></app-no-connection>

    <app-main></app-main>

</div> 

答案 5 :(得分:1)

安全的方法来监听网络状态

上面给出的答案很好用,但不是安全的方法。

1。不应直接引用依赖于浏览器的对象(例如window),请始终检查平台。

2。此外,必须将诸如网络连接之类的功能封装到服务中。

下面是ConnectionService,可以订阅以监听网络状态。它遵循 rxjs 6 样式。

完整代码

import { Injectable, Inject, PLATFORM_ID } from '@angular/core';
import { Observable, fromEvent, merge, empty } from 'rxjs';
import { isPlatformBrowser } from '@angular/common';
import { mapTo } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})
export class ConnectionService {

  private connectionMonitor: Observable<boolean>;

  constructor(@Inject(PLATFORM_ID) platform) {
if (isPlatformBrowser(platform)) {
  const offline$ = fromEvent(window, 'offline').pipe(mapTo(false));
  const online$ = fromEvent(window, 'online').pipe(mapTo(true));
  this.connectionMonitor = merge(
    offline$, online$
  );
} else {
  this.connectionMonitor = empty();
}



 }

  monitor(): Observable<boolean> {
    return this.connectionMonitor;
  }
}

在组件中,您可以通过订阅monitor()或使用异步管道直接进入HTML来监听。

答案 6 :(得分:0)

使用这个简单的Hack。

在5或更高版本中工作

 constructor(){
    setInterval(()=>{
       if(navigator.onLine){
         //here if it is online
       }else{
        //here if it is offline
       }
    }, 100)
 }

在app.component.ts的构造函数或您的应用程序引导程序中编写此代码 不需要任何外部库..

答案 7 :(得分:0)

import { Injectable } from '@angular/core';
import {
    HttpRequest,
    HttpHandler,
    HttpEvent,
    HttpInterceptor
} from '@angular/common/http';
import { Observable } from 'rxjs/Observable';

@Injectable()
export class InternetInterceptor implements HttpInterceptor {
    constructor() { }

    intercept(request: HttpRequest<any>, next: HttpHandler): Observable<HttpEvent<any>> {
        // check to see if there's internet
        if (!window.navigator.onLine) {
            // if there is no internet, throw a HttpErrorResponse error
            // since an error is thrown, the function will terminate here
            return Observable.throw(new HttpErrorResponse({ error: 'Internet is required.' }));

        } else {
            // else return the normal request
            return next.handle(request);
        }
    }
}

答案 8 :(得分:-2)

使用此功能。

没有任何外部库。

public isOnline: boolean = navigator.onLine;

ngOnInit() { 
    console.log(this.isOnline); 
}