2020-05-08 09:16:00
从西门子PLC的HTML页面读取JSON数据并处理跨域与语法错误的实用方法包括:将PLC输出的非标准JSON内容封装为JavaScript字符串变量,通过JSONP绕过跨域限制,并在客户端进行字符串清理和解析。
问题背景与挑战西门子S7-1200 PLC的Web服务器(如api.htm)可能返回类似JSON的非标准数据,存在以下问题:
HTML与JSON冲突:数据以HTML形式提供,但内容类似JSON。
非标准JSON语法:使用::=作为键值分隔符,值后有多余冒号(如"Muntje"::="Feedback-WS".Muntje:),导致标准解析器报错。
跨域限制(CORS):浏览器阻止外部域名通过AJAX直接请求PLC页面,JSONP可能因非标准格式失效。
解决方案:字符串封装与客户端解析核心思路:将PLC输出的非标准JSON封装为JavaScript字符串变量,通过<script>标签加载,避免语法错误,再在客户端清理并解析数据。
步骤1:修改PLC的api.htm文件将原始非标准JSON包裹在JavaScript变量声明中,例如:
let rawDataFromPLC = `{ "Muntje"::="Feedback-WS".Muntje:, "AdK"::="Feedback-WS".Aanraking_der_Kunst:, // ...其他数据...}`;使用反引号(`)定义多行字符串,若PLC环境不支持,可改用单引号或双引号,并手动处理换行和转义。
步骤2:客户端AJAX请求配置使用dataType: "jsonp"绕过跨域限制,但需注意PLC返回的是JS变量而非标准JSONP回调。示例配置:
var settings = { 'cache': false, 'dataType': "jsonp", 'async': true, 'crossDomain': true, 'url': "由于PLC未返回标准JSONP回调,response参数可能为undefined,数据需从全局变量rawDataFromPLC中获取。
步骤3:客户端数据清理与解析在AJAX的done回调中,对rawDataFromPLC进行以下处理:
替换非标准分隔符:将::=替换为标准冒号:。let validJsonString = rawDataFromPLC.replace(/::=/g, ':');
移除多余冒号:例如将"value:"修正为"value"(根据实际数据调整正则表达式)。
解析为JSON对象:使用JSON.parse()解析清理后的字符串。try { const parsedData = JSON.parse(validJsonString); console.log(parsedData);} catch (error) { console.error("解析失败:", error);}
关键注意事项
PLC环境限制:若无法修改api.htm,需在客户端通过正则表达式直接处理原始响应文本(如从<script>标签的src响应中提取字符串)。
错误处理:使用try-catch捕获解析错误,避免因语法问题导致脚本中断。
安全性:确保PLC的Web服务器配置允许外部访问,并限制敏感数据的暴露。
替代方案(若无法修改PLC输出)若无法修改api.htm,可在客户端通过以下方式处理:
使用dataType: "text"获取原始HTML文本。
通过正则表达式提取其中的非标准JSON字符串(如匹配{...}内容)。
按上述步骤清理并解析字符串。
此方法通过变通手段解决了跨域与非标准JSON的兼容性问题,适用于工业自动化场景中PLC数据与前端应用的集成。