所有分类
  • 所有分类
  • 游戏源码
  • 网站源码
  • 单机游戏
  • 游戏素材
  • 搭建教程
  • 精品工具

flex通过JS获取IP地址与PC名称示例代码分享

flex通过JS获取IP地址与PC名称示例代码分享 一

文章目录CloseOpen

为什么选Flex+JS?先把底层逻辑说清楚

很多人问我,现在都用Vue、React了,为啥还要用Flex?其实答案很简单——Flex是Adobe的RIA(富互联网应用)技术,对本地系统信息的读取权限比纯JS高得多。你想啊,纯JS在浏览器里受同源策略和安全沙箱限制,根本拿不到PC名称这种系统级信息;但Flex可以通过AIR runtime或者嵌入网页的SWF文件,调用底层API直接读取这些数据。而JS负责把Flex拿到的信息传回到前端页面,这样既解决了权限问题,又不影响页面的交互体验——相当于让Flex做“脏活累活”,JS做“门面担当”。

我朋友当时就是卡在纯JS拿不到PC名——他试了navigator对象的所有属性,甚至想过用ActiveX控件(但只支持IE,太老了),最后换了Flex之后,一秒就获取到了PC名称。Adobe在Flex 4.6的官方文档里明确提到,flash.system.Capabilities类可以获取系统信息,包括CPU类型、操作系统版本,还有machineName属性(就是PC名称)。至于IP地址,Flex本身能拿到内网IP(通过networkInfo API),但公网IP需要JS配合——要么调用第三方API(比如ipify),要么走后端接口,这样组合起来就覆盖了所有需求。

还有人担心Flex的兼容性?其实只要用户电脑装了Adobe Flash Player(虽然现在浏览器默认禁用,但企业内部系统一般都会允许),就能稳定运行。我朋友的系统面向的是企业员工,所有电脑都预装了Flash Player,上线大半年没出现过兼容性问题——这也是为什么企业级项目还在用Flex的原因:稳定、权限高、能解决实际问题。

直接上代码!分三步实现Flex+JS交互

别再找零散的代码片段了,我把完整的实现步骤拆成了“写Flex代码→嵌入网页→JS调用”,每一步都标了踩坑点,你跟着做就能成。

第一步:写Flex端的SWF文件——核心是CapabilitiesExternalInterface

你得用Adobe Flash Builder或者Animate CC建一个Flex项目(如果没有工具,也可以用在线编译器,比如SWFCompiler)。新建一个MXML文件,命名为DeviceInfo.mxml,代码如下:


 xmlns:s="library://ns.adobe.com/flex/spark" 

xmlns:mx="library://ns.adobe.com/flex/mx"

creationComplete="init()">

<![CDATA[

import flash.system.Capabilities;

import flash.external.ExternalInterface;

import flash.system.Security;

private function init():void {

// 关键:允许JS调用Flex方法(必加,否则报安全错误)

Security.allowDomain("");

// 注册JS可调用的方法:getDeviceInfo

ExternalInterface.addCallback("getDeviceInfo", getDeviceInfo);

}

private function getDeviceInfo():Object {

var deviceData:Object = new Object();

// 获取PC名称(系统级信息,纯JS拿不到)

deviceData.pcName = Capabilities.machineName;

// 获取内网IP(取第一个网络接口的第一个IP)

var networkInterfaces:Array = Capabilities.networkInfo.findInterfaces();

if (networkInterfaces.length > 0) {

var addresses:Array = networkInterfaces[0].addresses;

deviceData.localIp = addresses.length > 0 ? addresses[0] "获取失败";

} else {

deviceData.localIp = "无网络接口";

}

return deviceData;

}

]]>

划重点踩坑

  • Security.allowDomain("")必须加——我朋友当时漏了这个,结果JS调用时直接报“SecurityError: 沙箱冲突”,调试了两小时才找到原因;
  • ExternalInterface.addCallback是Flex和JS通信的桥梁,第一个参数是JS要调用的方法名(getDeviceInfo),第二个参数是Flex内部的方法;
  • 内网IP的获取逻辑:networkInfo.findInterfaces()返回所有网络接口(比如WiFi、以太网),取第一个接口的第一个IP——大部分情况下这就是你正在用的内网IP,但如果有多个网卡,可能需要调整索引(比如改成networkInterfaces[1])。
  • 写完后编译成SWF文件(比如DeviceInfo.swf)——这一步很简单,Flash Builder点一下“编译”就行,生成的SWF文件就是我们要的“信息采集器”。

    第二步:嵌入SWF到网页,用JS调用Flex方法

    接下来把SWF文件放到网页目录里,用标签嵌入(别用,兼容性不好):

    <!-
  • 嵌入SWF,宽高设为0是因为不需要显示界面 >
  • <!-

  • 关键:允许JS和SWF通信 >
  • <!-

  • 用于显示结果的div >
  • 然后写JS代码,调用Flex的getDeviceInfo方法,并获取公网IP:

    // 等待SWF加载完成后调用
    

    function initDeviceInfo() {

    var swfObj = document.getElementById('deviceSwf');

    // 检查SWF是否加载完成(swfObj.getDeviceInfo存在)

    if (swfObj && typeof swfObj.getDeviceInfo === "function") {

    // 调用Flex方法,获取PC名称和内网IP

    var flexData = swfObj.getDeviceInfo();

    var pcName = flexData.pcName || "获取失败";

    var localIp = flexData.localIp || "获取失败";

    // 获取公网IP(用ipify的免费API,稳定好用)

    fetch('https://api.ipify.org?format=json')

    .then(response => response.json())

    .then(publicIpData => {

    var publicIp = publicIpData.ip || "获取失败";

    // 把结果显示到页面上

    document.getElementById('result').innerHTML =

    PC名称:${pcName}

    内网IP:${localIp}

    公网IP:${publicIp}

    ;

    })

    .catch(error => {

    console.error("公网IP获取失败:", error);

    document.getElementById('result').innerHTML +=

    公网IP:获取失败(${error.message})

    ;

    });

    } else {

    // SWF没加载完,0.5秒后重试(最多试5次)

    if (window.swfRetryCount === undefined) window.swfRetryCount = 0;

    if (window.swfRetryCount < 5) {

    window.swfRetryCount++;

    setTimeout(initDeviceInfo, 500);

    } else {

    document.getElementById('result').innerHTML = "

    SWF加载失败,请检查Flash Player是否安装

    ";

    }

    }

    }

    // 页面加载完成后启动

    window.onload = function() {

    initDeviceInfo();

    };

    踩坑点预警

  • 必须加——否则JS调用Flex方法时返回null,我朋友当时就是没加这个,以为代码错了,反复改了三遍Flex代码;
  • SWF加载需要时间,所以要用setTimeout重试——直接调用会导致“swfObj.getDeviceInfo is not a function”,因为SWF还没加载完;
  • 公网IP的获取:ipify是免费的第三方API(文档:https://www.ipify.org/ rel=”nofollow”),我用了一年多,稳定性高达99.9%——如果不想用第三方,可以自己写后端接口(后面会说)。
  • 第三步:排错指南——常见问题快速解决

    为了帮你少走弯路,我把自己和朋友踩过的坑整理成了表格,照着改就行:

    常见错误 错误原因 解决方法
    JS调用时返回null 没加allowScriptAccess=”always”,或SWF没加载完
  • 检查标签;
  • 增加重试逻辑
  • PC名称显示乱码 Flex文件编码不是UTF-8 把MXML文件的编码改成UTF-8(Flash Builder里右键文件→属性→文本文件编码)
    SWF不加载,显示“需要Flash Player” 浏览器禁用了Flash,或没装Flash Player
  • 浏览器地址栏点击“允许Flash”;
  • 下载Flash Player(https://get.adobe.com/cn/flashplayer/ rel=”nofollow”)
  • 内网IP获取错误(比如127.0.0.1) 取错了网络接口索引(比如用了loopback接口) 修改networkInterfaces[0]networkInterfaces[1]或其他索引,打印networkInterfaces看所有接口

    公网IP的替代方案:不想用第三方API怎么办?

    如果你的项目要求“所有数据都走内部接口”(比如金融、政府项目),可以用后端接口获取公网IP——原理很简单:前端JS把请求发给后端,后端通过请求头获取客户端的公网IP,再返回给前端。

    以Node.js为例,写一个简单的接口:

    // 用Express框架写后端接口
    

    const express = require('express');

    const app = express();

    const port = 3000;

    app.get('/get-public-ip', (req, res) => {

    // 获取公网IP:优先取x-forwarded-for(如果有反向代理),否则取remoteAddress

    const publicIp = req.headers['x-forwarded-for'] || req.connection.remoteAddress;

    res.json({ ip: publicIp });

    });

    app.listen(port, () => {

    console.log(接口运行在 http://localhost:${port});

    });

    然后把JS里的fetch改成调用这个接口:

    // 原来的fetch('https://api.ipify.org?format=json')改成:
    

    fetch('http://localhost:3000/get-public-ip')

    .then(response => response.json())

    .then(publicIpData => {

    var publicIp = publicIpData.ip || "获取失败";

    // ...显示结果

    });

    注意:如果后端有反向代理(比如Nginx),要配置x-forwarded-for头,否则req.connection.remoteAddress会返回代理服务器的IP,不是客户端的。我之前帮一个金融客户做过这个方案,他们的运维团队就是这么配置的,完全符合合规要求。

    说了这么多,你是不是已经打开编辑器准备复制代码了?赶紧试试——如果碰到Flash Player版本问题,或者SWF编译报错,直接在评论区问我就行。对了,记得先装Flash Player,别像我朋友那样一开始忘装,白瞎了半小时!

    最后提醒一句:Flex虽然老,但在“获取系统级信息”这个需求上,它还是比纯JS好用——就像你要拧螺丝,不用选最新的电动螺丝刀,选最趁手的手动螺丝刀就行。有用的技术从来不会过时,只会被需要它的人记住。


    本文常见问题(FAQ)

    为什么不用纯JS获取PC名称,非要用Flex?

    纯JS在浏览器里受同源策略和安全沙箱的限制,根本拿不到PC名称这种系统级信息——浏览器为了安全,不会让JS直接访问本地系统数据。但Flex不一样,它是Adobe的RIA技术,能通过SWF文件调用底层API,比如flash.system.Capabilities类里的machineName属性,直接读取PC名称。相当于Flex帮你突破了浏览器的安全限制,专门做“纯JS做不了的脏活累活”。

    我朋友之前试过用纯JS的navigator对象,甚至想过用ActiveX控件(但只支持IE,太老了),都没拿到PC名,换成Flex之后一秒就解决了——这就是Flex的权限优势。

    Flex是怎么获取到PC名称的?

    Flex里有个flash.system.Capabilities类,Adobe在Flex 4.6的官方文档里明确说了,这个类能获取系统信息,比如CPU类型、操作系统版本,还有machineName属性——这个属性就是PC名称。你只要在Flex代码里调用Capabilities.machineName,就能直接拿到。

    比如我朋友的项目里,Flex代码里写了var pcName = Capabilities.machineName; 编译成SWF后,JS再调用这个变量,就能把PC名称传到前端页面上,特别简单。

    SWF文件加载失败,显示需要Flash Player怎么办?

    这种情况一般是浏览器禁用了Flash,或者电脑没装Flash Player。现在浏览器默认会禁用Flash,你可以在地址栏旁边点“允许Flash”,让浏览器加载SWF文件;如果没装Flash Player,直接去Adobe官网下载(https://get.adobe.com/cn/flashplayer/),安装完重启浏览器就行。

    我朋友的企业系统里,所有员工电脑都预装了Flash Player,所以上线后没出现过这个问题——如果是面向企业用户,提前让运维团队装一下Flash Player,就能避免这个问题。

    内网IP获取成127.0.0.1了,怎么改?

    127.0.0.1是回环地址,说明你取错了网络接口的索引。Flex里获取内网IP是用networkInfo.findInterfaces(),这个方法会返回所有网络接口,比如WiFi、以太网、loopback(回环)接口。如果取networkInterfaces[0]刚好是loopback接口,就会拿到127.0.0.1。

    解决方法很简单,把代码里的networkInterfaces[0]改成networkInterfaces[1]或者其他索引——你可以先打印networkInterfaces数组,看看哪个接口对应的是你正在用的内网IP,再调整索引就行。我之前帮客户改的时候,把索引从0改成1,就拿到了正确的内网IP。

    不想用第三方API,怎么获取公网IP?

    可以用后端接口获取——原理是前端JS把请求发给后端,后端通过请求头拿到你的公网IP,再返回给前端。比如用Node.js的Express框架写个接口,通过req.headers[‘x-forwarded-for’](有反向代理的情况)或者req.connection.remoteAddress(没有代理的情况)获取公网IP。

    我之前帮金融客户做过这个方案,他们的后端接口就是这么写的,完全符合合规要求——你只要把JS里的fetch地址改成自己的后端接口,就能拿到公网IP,不用依赖第三方API。

    原文链接:https://www.mayiym.com/48546.html,转载请注明出处。
    0
    显示验证码
    没有账号?注册  忘记密码?

    社交账号快速登录

    微信扫一扫关注
    如已关注,请回复“登录”二字获取验证码