尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

Link入门全解:网页新标签打开、网络链路聚合与PLC通信协议

Link入门全解:网页新标签打开、网络链路聚合与PLC通信协议 做技术这行久了你会发现很多基础概念翻来覆去就那么点东西但每次重新回头去理解又总能有新的收获。“Link”这个词就是典型它算得上是我入行以来接触频率最高的词之一但不同场景下它代表的东西完全不一样——前端同学聊的是a标签和页面跳转网络工程师聊的是链路聚合和端口绑定做工业自动化的朋友开口却是PLC通信协议。这篇内容我就想顺着“Link”这个线索把这几个领域里最常见的“Link入门”知识串起来聊一聊重点讲清楚网页链接处理脚本、网络链路聚合、以及工业场景下Host Link这类通信协议到底是怎么回事适合刚入门的技术新人也适合那些一直用但从来没深究过“Link背后原理”的朋友。1. 内容整体设计与思路拆解1.1 一个词三个世界先说说我为什么想把这三块内容放在一起讲。很多初学者在搜索“Link入门”的时候其实自己也不太清楚要找的是哪个方向的资料。有人是因为写网页时被target_blank折腾得够呛想知道怎么用脚本来控制新标签页的打开行为有人是配置交换机或者Linux服务器时遇到了bridge aggregation和link aggregation的选择困难还有人是在工控现场拿到一台基恩士或者台达的PLC面对Host Link指令一脸茫然。我在实际工作中发现这三类需求背后有一个共同点**大家都在处理“连接”这件事只是连接的层级和方式不同。**网页里的Link是应用层的连接解决的是用户体验问题网络设备里的Link是数据链路层的连接解决的是带宽和冗余问题PLC通信协议里的Link是设备与设备之间的连接解决的是工业现场的数据交互问题。所以这篇文章的思路不是按某个单一技术栈去讲而是按照“应用层 → 网络层 → 工业现场”这个递进关系来拆解Link的不同形态。每部分我都会从最核心的原理讲起再落到具体可操作的配置或代码上最后附上实际踩坑的经验。1.2 为什么从脚本开始讲网页Link网页里的Link应该是大多数人最早接触的概念。但大多数教程只告诉你a hrefxxx是超链接target_blank可以在新标签页打开却很少讲为什么有时候需要脚本干预以及脚本到底解决了什么问题。举个实际例子我们做一个后台管理系统运营人员经常需要批量审核内容每个审核项都要打开对应的详情页。如果所有详情页都用target_blank新开用户一天可能开几十个标签页浏览器崩溃不说管理成本也高。这时候就需要用脚本来控制——比如长按Ctrl才新开普通点击在当前页跳转或者通过右键菜单自定义打开行为。这就是open link in new tab脚本存在的意义它本质上是在给链接的默认行为做一层定制化的用户交互控制。我在第三部分会给出一个可以直接用的脚本方案包括如何判断用户是否按了修饰键、如何动态插入链接、以及如何做事件委托这些细节是网上很多教程不会讲透的。1.3 网络和PLC里的Link为什么值得认真学如果说网页Link是入门级的话网络链路聚合和PLC通信协议就是进阶甚至工程级的“硬核Link”。网络设备上配置Link Aggregation链路聚合可以同时提升带宽和可靠性而Bridge Aggregation桥接聚合在一些场景下要解决的问题又略有不同两者不认真区分的话配置错了网络直接不通排障的时候非常痛苦。PLC那边的Host Link协议也是同理。基恩士的Host Link和台达的PLC Link都是一种基于串口或以太网的通信协议它们的帧格式、地址映射规则和指令集各不相同。不少工程师第一次接触到这些协议时光是对照手册去查指令码就花了好几天更别提自己在PC上写测试程序去裸调协议了。这部分内容我建议不管是做网络还是做工业自动化的朋友都认真看一看。即使你现在用不到理解了“不同层次的Link分别解决什么问题”这个框架之后以后再遇到各种带Link的技术名词至少能快速定位它属于哪个层级、解决什么问题。2. 核心细节解析与实操要点2.1 网页Link脚本从基础属性到事件委托先明确一个基础概念在HTML里链接的本质是a元素它的href属性定义了目标地址target属性定义了打开方式。target_blank代表在新标签页打开target_self代表在当前页打开。但如果你要写一个“在新标签页打开链接”的脚本光处理target是不够的还需要考虑用户的实际操作习惯。一个比较完整的open link in new tab脚本需要考虑这些点判断触发方式鼠标左键点击、中键点击、键盘回车触发行为应该不同判断修饰键状态按住CtrlWindows或CmdMac时应该强制新标签打开处理动态内容页面里通过JS后渲染出来的链接需要用到事件委托来统一接管安全性处理所有外部链接加上relnoopener noreferrer防止新页面通过window.opener操作原页面。我见过很多人写脚本只处理了前面两条结果页面里用了Vue或者React之后新渲染出来的链接根本没被脚本接管还得在组件生命周期里重新绑定麻烦得很。正确的做法是直接在document上做事件委托这样不管是首屏就存在的链接还是后来动态渲染的链接统统都跑不掉。2.2 链路聚合Bridge Aggregation与Link Aggregation的本质区别网络设备里的“Link”主要指物理链路。当两台交换机之间只有一根线连接时带宽上限就被这根线锁死了而且线断了就断网。链路聚合Link Aggregation的核心思路是把多根物理链路绑在一起逻辑上变成一根更宽的链路既增加了带宽又实现了冗余。这里需要特别区分的是Bridge Aggregation桥接聚合。在Linux里用bridge link命令和ip link命令操作时这两个概念容易混淆。简单来说Link Aggregation通常叫bonding或port channel工作在网络接口层多个物理网卡聚合成一个逻辑网卡IP层只看到一个接口Bridge Aggregation工作在二层桥接层多个物理接口先加入一个网桥再把网桥作为一个整体去参与STP生成树协议或者其他二层协议的计算。我用一个生活化的类比来解释Link Aggregation就像是把多条高速公路合成一条超级宽的高速公路车流量可以平摊到所有车道上Bridge Aggregation则更像是多个收费站合并成一个大的收费站群每个出口都能走但整体的收费策略和管理是统一的。实际操作中Linux下配置Link Aggregation最常用的是bonding模块配置文件在/etc/modprobe.d/bonding.conf而在等保和大型组网场景下交换机上配置Link Aggregation通常是先建一个Eth-Trunk口再把物理口加入进去。配置的时候要注意两端设备的聚合模式必须一致常用的模式有静态LACPLink Aggregation Control Protocol和手工聚合。2.3 工业PLC的Host Link协议读懂帧就是读懂设备工业自动化场景里的Host Link是基恩士KeyencePLC上非常经典的一种通信协议。它的名字容易让人误以为和网页Link或者网络Link有关系其实它指的是上位机Host通过串口或以太网与PLC可编程逻辑控制器进行通信时使用的一套指令格式。Host Link协议的核心是“帧”的概念。每一次通信上位机都要发送一个请求帧PLC返回一个响应帧。请求帧里包含了节点号、命令码、地址、数据等内容。比如要读取KV系列PLC的D100这个数据寄存器的值需要按照帧格式拼出一串ASCII字符发送过去然后从返回帧里解析出当前值。这里牵扯到很多人容易搞错的点地址对应关系。不同型号的PLC内部地址编号不一样同一个“D100”在不同协议版本下可能对应不同的内部存储区。我在第三节会给出基恩士和台达PLC Link的地址对照思路和实际调试方法帮助大家少走弯路。2.4 为什么台达PLC Link和基恩士Host Link常被放在一起说在很多工控项目里台达PLC和基恩士PLC常常因为性价比和供货原因被替换使用。替换的时候通信协议就成了一个绕不开的问题。台达的PLC Link协议例如DVP系列支持的Link通信和基恩士的Host Link协议虽然都叫“Link”但帧格式完全不同连通信参数波特率、数据位、校验位都不一定能对上。举一个我实际遇到过的项目原来用的基恩士KV-5500上位机通过Host Link走RS-232和它通信。客户后来要换成台达DVP-14SS我一看如果继续在原有的上位机软件里直接改IP和端口是行不通的必须把原来基于Host Link帧的解析代码整个换成台达的通信指令格式。这中间还涉及地址偏移的计算比如输入点、输出点、中间继电器的地址映射都不同需要重新做一张对照表。3. 实操过程与核心环节实现3.1 实现一个带事件委托的新标签页打开脚本先上一个我常用的、比较健壮的open link in new tab脚本。它可以直接嵌入任何项目不依赖框架document.addEventListener(click, function (e) { // 找到实际的 a 标签兼容点击内部子元素的情况 const anchor e.target.closest(a); if (!anchor) return; const href anchor.getAttribute(href); if (!href || href.startsWith(#) || href.startsWith(javascript:)) { return; // 跳过空链接和锚点链接 } const newTab e.ctrlKey || e.metaKey || e.which 2 || e.button 1; if (newTab) { // 如果是新标签页打开安全加固 anchor.setAttribute(target, _blank); anchor.setAttribute(rel, noopener noreferrer); return; // 交给浏览器默认行为 } // 可配置默认是否强制新标签打开 const forceNewTab true; if (forceNewTab !anchor.target) { e.preventDefault(); window.open(href, _blank, noopener,noreferrer); } }, true);这里的要点有几个e.target.closest(a)非常关键。因为用户点击的可能不是a本身而是它里面的span、img或者div如果不做closest查找事件取到的target就不包含href属性逻辑会直接失效。e.which 2或者e.button 1是鼠标中键的判断。浏览器默认中键点击链接就是新标签页打开我们的脚本只补足默认行为不支持的部分。capture参数第三个参数为true我建议加上。这样可以在事件冒泡到其他处理函数之前就拦截下来避免页面里其他业务脚本先执行了preventDefault导致链接打不开。关于window.open的第三个参数在新版浏览器里推荐写成noopener,noreferrer。注意这个参数在不同浏览器中可能会有兼容性差异但它主要是安全兜底实际使用中我发现更多的场景是直接设置target_blank配合relnoopener更通用。网上搜索时经常看到有人问“为什么我写的跳转脚本在某些浏览器里不起作用”绝大多数都是因为没处理中键、没处理动态元素或者没加捕获阶段。上面这段代码基本把这三个坑都填了。3.2 网络设备上的Link Aggregation配置实例以常见的Linux服务器双网卡绑定为例讲一个实际可操作的链路聚合配置流程。假设服务器有两块物理网卡eth0和eth1要通过mode 4802.3ad即LACP与交换机对接。第一步安装必要的工具包apt install ifenslave # Debian/Ubuntu # 或者 yum install iputils # 老版本CentOS使用新版建议用NetworkManager或systemd-networkd第二步创建bonding接口。以systemd-networkd为例在/etc/systemd/network/下面创建两个文件# /etc/systemd/network/10-bond0.netdev [NetDev] Namebond0 Kindbond [Bond] Mode802.3ad TransmitHashPolicylayer34 MIIMonitorSec1s LACPTransmitRatefast# /etc/systemd/network/20-bond0.network [Match] Namebond0 [Network] DHCPno Address192.168.10.10/24 Gateway192.168.10.1 DNS114.114.114.114第三步把物理网卡加入bond# /etc/systemd/network/eth0.network [Match] Nameeth0 [Network] Bondbond0eth1.network同样配置。配置好后systemctl restart systemd-networkd用ip link确认bond0的状态是UP并且能看到两个slave接口。我实测下来mode 4模式下做完这一步带宽和冗余都生效了。再进一步用cat /proc/net/bonding/bond0能看到详细的LACP状态包括每个slave是处于“up”还是“down”。这里有一个我在现场踩过的大坑如果交换机端口用的是手工聚合模式static trunkLinux这边一般要配平衡轮询模式mode 0两边必须严格对应。有一次我这边配了802.3ad交换机那边没开LACP结果链路状态显示up但实际业务流量全部丢包排查了一个多小时。所以配置前一定要先确认对端设备支持的聚合方式。如果是华为交换机对应的配置大致如下interface Eth-Trunk1 mode lacp-static port link-type trunk port trunk allow-pass vlan 10 20 # interface GigabitEthernet0/0/1 eth-trunk 1 # interface GigabitEthernet0/0/2 eth-trunk 1华为的设备上叫Eth-Trunk思科叫PortChannelH3C也叫Eth-Trunk各家的命令风格不太一样但原理都是把多个物理口绑成一个逻辑口。3.3 基恩士Host Link协议的帧结构拆解与调试脚本基恩士Host Link协议用于上位机和PLC之间通信分为C模式Command Mode和Q模式Query Mode。我对C模式比较熟这里以C模式读取PLC的D寄存器为例做拆解。发送帧的一般格式 节点号 命令码 地址 数据 FCS 终止符帧起始符固定0x40节点号PLC侧设置的通信节点编号例如01命令码例如RD代表读WD代表写还有RDS、WDS等批量操作命令地址要访问的PLC内部地址比如D100在KV系列里会映射成类似D00100的格式FCS帧校验和通常是把之后到FCS之前的所有字符按ASCII码做异或计算再转成2位十六进制字符串终止符通常是*加回车换行0x2A 0x0D。举个例子读取节点号为01的PLC的D100寄存器值帧内容大概是01RD00100??*这里的??就是计算出来的FCS。搞明白这个之后剩下的工作就是写脚本去拼帧、发串口、收响应、解析响应帧。我习惯用Python的pyserial库做这种协议的快速验证简化的示例代码import serial def calc_fcs(payload: bytes) - str: fcs 0 for b in payload: fcs ^ b return f{fcs:02X} def build_read_command(node: str, address: str) - bytes: body f{node}RD{address}.encode(ascii) fcs calc_fcs(body[1:]) # 从之后开始异或 return body f{fcs}*\r.encode(ascii) ser serial.Serial(COM3, 9600, timeout1) cmd build_read_command(01, D00100) ser.write(cmd) resp ser.read(64) print(resp)注意不同PLC型号对地址格式的要求不一样。有些老款KV系列在地址补零位数上有严格要求比如D100必须写成D00100写D100直接报错。遇到这种情况最快的办法是拿基恩士官方手册里的地址范围表对照一遍。3.4 台达PLC Link的地址映射与通信参数设置台达PLC的“Link”通信主要是指DVP系列PLC的通信协议。它同样基于串口或以太网但帧格式完全不同于基恩士的Host Link。台达DVP的通信地址通常要换算成协议的“内部地址”比如输入点X对应的通信地址是0x0800开始输出点Y对应的通信地址是0x0800 输出点数内部继电器M从0x0800往后偏移D寄存器从0x1000开始。很多人一听到“地址偏移”头就大但我理解下来其实就是一张表PLC程序里看到的是“软元件名”协议里用的是“内存地址号”中间差一个固定的偏置量。只要能通过手册或者PLC软件把这块偏移表下载下来后续写代码就是套公式。通信参数方面台达DVP一般出厂是9600波特率、7位数据位、偶校验Even、1位停止位。而基恩士的默认设置可能是9600、8位数据位、无校验。所以在做设备替换时光改协议还不行串口参数也必须一起调整否则物理层就过不去。4. 常见问题与排查技巧实录4.1 网页链接脚本的典型问题速查现象可能原因解决办法中键点击无效脚本只监听了click事件中键默认行为被其他代码拦截在mousedown或auxclick事件里补一份监听动态渲染的链接无法处理没有用事件委托直接在某个DOM节点上绑事件改在document级别做closest()委托新开页面被浏览器拦截window.open不是由用户手势直接触发的确保window.open在事件回调的同步执行路径里调用外部链接存在安全风险新标签页没有加relnoopener统一在脚本里做安全加固我还想强调一个容易被忽略的点很多人写得链接脚本会忽略href里的协议判断。javascript:开头的链接虽然现在很少用了但一些老旧的内部系统里还有处理不当会造成XSS风险。4.2 链路聚合排查实录在网络这一侧最常见的现象是“聚合后反而更慢”或者“完全不通”。我总结了一个排查顺序先看物理层所有参与聚合的网线都插好了吗两端设备的光模块/电口速率和双工模式是否一致再看协议层LACP状态是否协商成功用ethtool bond0或交换机上的display eth-trunk 1查看对端状态三看流量分片很多聚合模式是按IP或MAC做哈希的如果流量源目地址都相同实际只会走一条物理链路带宽翻不了倍这是正常的不是故障最后看VLAN聚合链路两端放行的VLAN要一致否则某些VLAN通了某些VLAN断了表现很诡异。4.3 串口通信协议调试的通用技巧工业串口通信调试时我一般先不用PLC软件直接用一个串口调试助手去验证协议。先把要发送的帧按16进制或者ASCII方式手动发一遍看PLC回不回响应如果能回证明物理链路和帧格式基本对了再上自己写的代码这样能快速把问题定位在“协议层”还是“代码层”。另外有个细节很多工控屏和PLC通信不成功不是协议格式错了而是串口接地和线序问题。RS-232的2、3脚交叉5脚共地这三根线只要接对大多数情况物理层就能通。如果用RS-485A/B方向接反了会有时通时不通的现象表现为“能发不能收”或者“偶尔收到乱码”。我在这种场景下从来不看电脑设备管理器里的“COM口已连接”提示它只能代表USB转串口模块被系统识别了不能代表串口线上真有数据在走。最可靠的办法还是用示波器或者逻辑分析仪看端口波形没有这些工具的时候至少可以短接2、3脚自发自收测试一下USB转串口模块本身是否完好。4.4 关于“Link”这个词的常见误区最后想聊聊我观察到的几个关于Link的普遍误区这也是很多“Link入门”资料里不会说清楚的东西。第一不要把网页链接的单击行为和新标签页打开方式混为一谈。链接是否在新标签页打开不是网页的核心功能而是一种交互体验设计不同产品有不同策略。比如文档型网站倾向于当前页打开方便连续阅读后台管理系统则多喜欢新标签页打开方便对照操作。第二网络里的“链路聚合”不是把两根网线随便插上就有双倍带宽。聚合的底层要靠哈希算法把不同的流量分散到不同链路上如果两端设备都支持LACP尽量用它来自动协商手工聚合虽然配置简单后续维护容易留坑。第三工业PLC通信里的Host Link协议并不“高级”它就是个很经典的ASCII协议。一旦你看懂了它的帧结构你会发现它比很多现代工业总线协议都要直观。真正难的不是协议本身而是搞清楚不同型号PLC之间的地址映射和寄存器规划。5. 一点个人的经验总结多说几句我在处理各种Link相关问题时的感受。很多人一想到“Link”就直接去搜快捷键、搜某个具体功能的设置方法但我建议养成一个更好的习惯先判断这个Link工作在哪个层级是用户交互层、网络数据链路层还是设备通信层。层级判断对了方案基本就清晰了剩下的就是查参数、看文档、调配置。另外不管是在网页端写脚本还是在网络设备上配聚合又或者是在PLC上调试Host Link协议我都坚持用最笨的方法验证基础写脚本前先在浏览器控制台手动执行一遍逻辑配聚合前先用直连线把单条链路测试通调协议前先拿串口助手把帧发通。基础通了之后再叠加复杂性排查起来会轻松很多。做技术的日子久了你会发现那些看起来乱七八糟的报错和故障最后追根溯源基本都是很基础的问题脚本绑定错了阶段链路模式没对齐或者串口参数少改了一位。Link这个技术点给了我一个很深的体会——很多技术概念看着分散但底层解决问题的思路是相通的。先把“连接”这件事吃透不管它是在浏览器里、在交换机上还是在PLC的串口后面你都能快速找到下手的地方。
返回列表