经过大量的研究/搜索,我能够使用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'.
预先感谢!
答案 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('');