获取本地客户端IP地址

时间:2018-10-22 19:16:29

标签: jquery angular typescript

经过大量的研究/搜索,我能够使用JQuery获取本地客户端IP地址并将其与Angular 6项目集成。尽管我得到了想要的东西,但是在构建应用程序时却遇到了错误。我认为这是因为Angular中嵌入了JQuery代码(特别是window.something)。

有人知道如何使用纯Angular实现此目标。没有JQuery,也没有第3方网址(例如https://www.whatismyip.com和许多其他网站)。

代码:

    ngOnInit() {
        var self = this;
        var localIp1 = ""; 
        $(document).ready(function(){
            window.RTCPeerConnection = window.RTCPeerConnection || window.mozRTCPeerConnection || window.webkitRTCPeerConnection;  
            var pc = new RTCPeerConnection({iceServers:[]}), 
            noop = function(){}; 

            pc.createDataChannel("");
            pc.createOffer(pc.setLocalDescription.bind(pc), noop);   
            pc.onicecandidate = function(ice){
                if(!ice || !ice.candidate || !ice.candidate.candidate)  return;

                var localIp = /([0-9]{1,3}(\.[0-9]{1,3}){3}|[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7})/.exec(ice.candidate.candidate)[1];
               // this.localIpAddress = myIP;
                localIp = localIp.replace(/\./g, '-');
                sessionStorage.setItem("LOCAL_IP", localIp);
                $.ajax({ 
                    type: "GET",
                    dataType: "json",
                    url: "http://localhost:8080/api/setLocalIpAddress/" + localIp,
                    success: function(data){        
                      console.log(data);
                    }
                 });
            };
        });
        this.localIp = sessionStorage.getItem("LOCAL_IP");
}

错误:

ERROR in src/app/selectline/select-line.component.ts(35,20): error TS2339: Property 'RTCPeerConnection' does not exist on type 'Window'.
src/app/selectline/select-line.component.ts(35,47): error TS2339: Property 'RTCPeerConnection' does not exist on type 'Window'.
src/app/selectline/select-line.component.ts(35,75): error TS2339: Property 'mozRTCPeerConnection' does not exist on type 'Window'.
src/app/selectline/select-line.component.ts(35,106): error TS2339: Property 'webkitRTCPeerConnection' does not exist on type 'Window'.
src/app/selectline/select-line.component.ts(39,16): error TS2339: Property 'createDataChannel' does not exist on type 'RTCPeerConnection'.

预先感谢!

2 个答案:

答案 0 :(得分:0)

我能够修改您上面的内容以及create an example StackBlitz,这些内容不使用jQuery或外部库。您可以点击该链接查看代码运行。

正如我在上面的评论中所述,您需要使用module augmentation documentation on the TypeScript handbook来执行此操作。为了增强window对象以识别您正在访问的全局属性,我添加了以下代码:

declare global {
  interface Window {
    RTCPeerConnection: RTCPeerConnection;
    mozRTCPeerConnection: RTCPeerConnection;
    webkitRTCPeerConnection: RTCPeerConnection;
  }
}

与您在上面的代码中使用的示例相比,RTCPeerConnection的规范的当前版本似乎已更改。修改它以符合当前规范,我得到了以下代码:

import { Component, NgZone } from '@angular/core';

declare global {
  interface Window {
    RTCPeerConnection: RTCPeerConnection;
    mozRTCPeerConnection: RTCPeerConnection;
    webkitRTCPeerConnection: RTCPeerConnection;
  }
}

@Component({
  selector: 'my-app',
  templateUrl: './app.component.html',
  styleUrls: [ './app.component.css' ]
})
export class AppComponent  {
  name = 'Angular';
  localIp = sessionStorage.getItem('LOCAL_IP');

  private ipRegex = new RegExp(/([0-9]{1,3}(\.[0-9]{1,3}){3}|[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7})/);

  constructor (private zone: NgZone) {
  }

  ngOnInit() {
    this.determineLocalIp();
  }

  private determineLocalIp() {
    window.RTCPeerConnection = this.getRTCPeerConnection();

    const pc = new RTCPeerConnection({ iceServers: [] });
    pc.createDataChannel('');
    pc.createOffer().then(pc.setLocalDescription.bind(pc));

    pc.onicecandidate = (ice) => {
      this.zone.run(() => {
        if (!ice || !ice.candidate || !ice.candidate.candidate) {
          return;
        }

        this.localIp = this.ipRegex.exec(ice.candidate.candidate)[1];
        sessionStorage.setItem('LOCAL_IP', this.localIp);

        pc.onicecandidate = () => {};
        pc.close();
      });
    };
  }

  private getRTCPeerConnection() {
    return window.RTCPeerConnection ||
      window.mozRTCPeerConnection ||
      window.webkitRTCPeerConnection;
  }
}

请注意,在onicecandidate方法中执行的代码将在Angular区域之外运行,因此当组件中的属性在该代码中更改时,它不会告诉Angular更新UI。为了让Angular知道更改,您需要获取对Angular区域的引用并在其中运行代码。这是通过this.zone.run(() => { ... });语法完成的。如果您想了解更多有关blog about zones in Angular的信息,请点击这里。

答案 1 :(得分:0)

以上答案中提到的https://stackblitz.com/edit/angular-get-local-ip上的示例对我不起作用。

我已经更新了示例中的行

$null = chcp # Run any console application to force the ISE to create a console.
$OutputEncoding = [Console]::InputEncoding = [Console]::OutputEncoding = [System.Text.UTF8Encoding]::new()

cmd.exe

我还更新了iceServers:pc.createDataChannel('');