新闻中心
从西门子PLC的HTML页面读取JSON数据:处理跨域与语法错误的实用方法

1. 背景与问题描述
在工业自动化领域,西门子S7-1200系列PLC常用于控制系统。有时,我们需要从PLC内置的Web服务器获取实时数据,并将其集成到外部Web应用程序中。一个常见的场景是,PLC的Web页面(例如api.htm)被设计成返回类似JSON的数据结构,以便前端应用可以解析和使用。然而,这里存在几个挑战:
- HTML格式与JSON内容的冲突:PLC为了方便自身操作变量,可能将数据以HTML文件的形式提供,即使其内容看起来像JSON。
-
非标准JSON语法:PLC生成的“JSON-like”数据可能包含非标准的语法,例如在键值对之间使用::=而不是:,或者在值后面有多余的:,这会导致标准的JSON解析器报错。
{ "Muntje"::="Feedback-WS".Muntje:, "AdK"::="Feedback-WS"
;.Aanraking_der_Kunst:,
// ... 其他数据 ...
"Morse_Code"::="Feedback-WS".Morse_Code:
}上述示例中,::=和值后面的,前的:都是非标准语法。
- 跨域请求限制(CORS):当外部Web服务器尝试通过AJAX请求PLC的Web页面时,由于协议、域名或端口不同,浏览器会触发跨域安全策略,阻止请求。
为了绕过跨域问题,开发者通常会尝试使用JSONP(JSON with Padding)。JSONP通过动态创建<script>标签来加载数据,绕过了同源策略。然而,当PLC返回的api.htm文件内容并非标准的JSONP格式(即不是一个函数调用包裹的JSON数据),而是包含非标准JSON语法的HTML时,浏览器在尝试将其作为J*aScript执行时,就会抛出Uncaught SyntaxError: unexpected token: ':'等错误。</script>
原始的AJAX请求配置如下:
立即学习“前端免费学习笔记(深入)”;
var settings = {
'cache': false,
'dataType': "jsonp", // 尝试使用JSONP绕过跨域
"contentType": "application/json; charset=utf-8",
"async": true,
"crossDomain": true,
"url": "http://192.168.22.160/awp/TIR/api.htm",
"method": "GET",
"headers": {
"accept": "application/json",
"Access-Control-Allow-Origin":"*"
}
};
$.ajax(settings).done(function (response) {
// console.log($.parseJSON(response)); // 在这里会遇到语法错误
});2. 解决方案:字符串封装与客户端解析
由于PLC的限制,我们可能无法直接修改其输出以生成标准的JSON或JSONP。一个实用的变通方案是:将PLC输出的“JSON-like”内容封装成一个J*aScript字符串变量,然后通过JSONP(或dataType: "script")加载这个包含字符串的J*aScript文件,最后在客户端对这个字符串进行清理和解析。
Kreado AI
Kreado AI是一个多语言AI视频创作平台,只需输入文本或关键词,即可创作真实/虚拟人物的多语言口播视频。 为创作者提供AI赋能
182
查看详情
2.1 修改PLC上的api.htm文件
核心思想是将PLC输出的非标准JSON内容包裹在一个J*aScript变量声明中。这样,当浏览器通过<script>标签加载这个文件时,它会执行这段J*aScript代码,并将包含数据的字符串赋值给一个变量,而不会因为非标准JSON语法而报错。</script>
假设原始的api.htm内容是:
{
"Muntje"::="Feedback-WS".Muntje:,
"AdK"::="Feedback-WS".Aanraking_der_Kunst:,
// ...
}修改后的api.htm内容应变为:
let rawDataFromPLC = `{
"Muntje"::="Feedback-WS".Muntje:,
"AdK"::="Feedback-WS".Aanraking_der_Kunst:,
"Juwelenkistje"::="Feedback-WS".Juwelenkistje:,
"Duivelsbeeld"::="Feedback-WS".Duivelsbeeld:,
"Klok"::="Feedback-WS".Klok:,
"Hertenpoot"::="Feedback-WS".Hertenpoot:,
"Zekering_Kledingkast"::="Feedback-WS".Zekering_Kledingkast:,
"Bed_knop_1"::="Feedback-WS".Bed_knop_1:,
"Bed_knop_2"::="Feedback-WS".Bed_knop_2:,
"Bed_knop_3"::="Feedback-WS".Bed_knop_3:,
"Bed_knop_4"::="Feedback-WS".Bed_knop_4:,
"Vacuum_Pomp"::="Feedback-WS".Vacuum_Pomp:,
"Signaal_Generator"::="Feedback-WS".Signaal_Generator:,
"Stekkerrek"::="Feedback-WS".Stekkerrek:,
"Zekering_1"::="Feedback-WS".Zekering_1:,
"Zekering_2"::="Feedback-WS".Zekering_2:,
"Zekering_3"::="Feedback-WS".Zekering_3:,
"Hoofdschakelaar"::="Feedback-WS".Hoofdschakelaar:,
"Morse_Code"::="Feedback-WS".Morse_Code:
}`;注意:这里使用了反引号 ` 来定义多行字符串,这在J*aScript中是合法的。如果PLC环境不支持,可以使用单引号或双引号,但需要手动处理换行和转义。
2.2 客户端AJAX请求与数据解析
在客户端,我们仍然可以使用dataType: "jsonp"来绕过跨域问题。当api.htm文件被加载为脚本时,它会执行let rawDataFromPLC = '...'语句,使得rawDataFromPLC变量在全局作用域(或特定作用域)中可用。然后,我们需要手动从这个变量中获取数据,并进行必要的字符串替换,使其成为有效的JSON,最后再进行解析。
// 在全局作用域声明一个变量来接收PLC数据
// 或者确保PLC文件中的变量名与此处一致,且在AJAX请求前或同一作用域内可访问
let rawDataFromPLC = '';
var settings = {
'cache': false,
'dataType': "jsonp", // 保持jsonp以绕过跨域,但要注意其行为
"contentType": "application/json; charset=utf-8", // 可能被jsonp忽略
"async": true,
"crossDomain": true,
"url": "http://192.168.22.160/awp/TIR/api.htm",
"method": "GET",
"headers": {
"accept": "application/json",
"Access-Control-Allow-Origin":"*" // 针对常规CORS请求,jsonp不依赖此
}
};
$.ajax(settings).done(function (response) {
// 对于非标准JSONP响应(即PLC返回一个JS变量声明),
// response参数通常是undefined或空对象,因为没有调用预期的回调函数。
// 数据需要从全局变量rawDataFromPLC中获取。
if (rawDataFromPLC) {
try {
// 步骤1: 替换PLC特有的键值分隔符 '::=' 为标准的 ':'
let validJsonString = rawDataFromPLC.replace(/::=/g, ':');
// 步骤2: 移除PLC特有的值后面的多余冒号,例如 'value:,' -> 'value,'
// 这个正则表达式会匹配冒号后紧跟逗号以上就是从西门子PLC的HTML页面读取JSON数据:处理跨域与语法错误的实用方法的详细内容,更多请关注其它相关文章!
# 数据结构
# 衡水网站排名优化
# 建设公司网站编号
# 诚信通怎么做关键词排名
# 含营销推广内容不被推荐
# 超级营销推广软件下载
# 佛山网站建设最新报价
# 汕头企业网站推广方法
# 夜场推广网站有哪些
# 安国短视频推广营销
# seo外连接分类举例
# 特有的
# 可以使用
# 使其
# 加载
# 是一个
# javascript
# 如何实现
# 客户端
# 非标准
# 关键词
# 回调
# access
# app
# 浏览器
# 正则表达式
# ajax
# json
# 前端
# js
# html
# java
相关栏目:
【
科技资讯46185 】
【
网络学院92790 】
相关推荐:
excel如何生成目录 excel一键生成工作表目录超链接
C++如何连接MySQL数据库_C++使用Connector/C++操作MySQL数据库教程
TikTok评论显示延迟如何处理 TikTok评论刷新优化方法
Composer的 archive 命令怎么用_快速打包你的PHP项目及其Composer依赖
Yandex搜索引擎官网入口_俄罗斯Yandex免登录一键直达
抖音隐秘迷城小游戏入口_ 抖音冒险解谜小游戏秒玩
vivo云服务网页版登录 怎么登录vivo云服务网页版
J*a编写用户注册与登录功能_掌握字符串与验证逻辑
腾讯QQ邮箱登录入口_QQ邮箱官方网站使用地址
Yandex搜索引擎一键访问入口_俄罗斯Yandex官网免登录
css绝对定位元素脱离父容器怎么办_确保父元素position非static
c++如何实现一个简单的ECS框架_c++数据驱动设计与游戏开发
抖音网页版企业服务中心登录入口_抖音网页版企业登录平台
J*aScript 字符串标签转换:使用正则表达式高效替换
Golang如何实现Web接口签名验证_Golang Web接口签名校验开发方法
百度网盘网页版入口 百度网盘网页版官方登录网址
抖音网页版怎么|直播|_抖音网页版开播操作指南
精准捕获:如何在页面中监听除特定元素外的所有点击事件
ArrayList与LinkedList操作复杂度详解:遍历与修改
AWS EC2实例间SQL Server连接超时:安全组配置与故障排除指南
将HTML动态表格多行数据保存到Google Sheet的教程
解决Python logging 中 datefmt 导致时间戳固定不变的问题
夸克AO3官网入口_AO3镜像网站2025推荐
sublime如何只显示或隐藏特定类型文件_sublime侧边栏文件过滤
高德地图总提示网络异常怎么办 高德地图离线导航设置与网络排查方法
可靠CSGO开箱平台解析 CSGO开箱网合集
Golang如何使用net/url解析URL_Golang URL解析与处理方法
在python-socketio事件处理器中安全访问Flask应用上下文
俄罗斯Yandex免登录入口_Yandex搜索引擎官网一键直达
荣耀Play7TPro怎样在信息App置顶客服对话_iPhone荣耀Play7TPro信息App置顶客服对话【优先查看】
豆包手机助手发布技术预览版:直接嵌入手机系统!努比亚样机发售
qq游戏大厅官方下载_qq游戏免费下载安装入口
J*a递归快速排序中静态变量导致数据累积问题的解决方案
Windows10怎么开启存储感知 Windows10系统设置自动清理临时文件释放C盘空间【教程】
拼多多赚钱渠道_拼多多收益来源
2026年CSGO开箱网站推荐 CSGO开箱平台精选
Mac终端命令大全_Mac常用Terminal指令速查
汽车之家官方网站官网入口_汽车之家网页版直接进入
html网页设计源代码怎么运行_运行html网页设计源代码步骤【指南】
解决 MongoDB 聚合查询中对象数组 _id 匹配问题
c++中为什么推荐使用using替代typedef_c++现代化类型别名
Angular Material 垂直步进器:实现底部到顶部排序的教程
J*aScript打印功能_j*ascript输出控制
基于动态规划的房屋花卉种植最小成本算法详解
NetBeans Ant项目:自动化将资源文件复制到dist目录的教程
在J*a中如何使用BigDecimal进行高精度计算_BigDecimal类应用指南
yy漫画网页版官方入口_yy漫画官网登录页面链接
文心一言怎样用插件调度API数据_文心一言用插件调度API数据【API调用】
漫蛙manwa2最新登录网址_漫蛙manwa2手机网页版入口
wps文字怎么插入目录并自动更新_wps文字如何插入目录并自动更新方法


2025-10-05
浏览次数:次
返回列表
;.Aanraking_der_Kunst:,
// ... 其他数据 ...
"Morse_Code"::="Feedback-WS".Morse_Code:
}