PHP插件开发中的一个错误:JSON直接输出导致网站首页异常

问题描述

最近在使用步数统计插件(WeFootStep)时,发现网站首页完全变成了一段JSON数据,而不是正常的HTML页面。具体表现为首页显示如下内容:

{"results":"<li><a href=\"https:\/\/blog.ybyq.wang\/archives\/186.html\">\u770b\u770b\u4f60\u662f\u4e0d\u662f\u201c\u8d5e\u535a\u6587\u76f2\u201d<p class=\"text-muted\">dobe\u3001IDEA\u3001<mark class='text_match'>pycharm<\/mark>\u7b49\r\n<\/p><\/a><\/li>..."}


这完全破坏了网站的正常浏览体验。

原因分析

经过几天的艰苦排查,发现问题出在WeFootStep插件的Widget.php文件中的getStepDataJson()函数:

/*** 获取步数JSON数据,用于AJAX请求*/
public function getStepDataJson()
{$history = $this->getStepHistory();$stats = $this->getStepStats();$data = ['history' => $history,'stats' => $stats];header('Content-Type: application/json');echo json_encode($data);exit;
}

这个函数存在的问题是:

  1. 函数直接设置了响应头为application/json
  2. 输出JSON编码后的数据
  3. 调用exit终止了PHP的执行流程

这种实现方式本来是为AJAX请求设计的,但如果在普通页面加载过程中被误调用,就会导致整个页面只输出JSON数据。

解决方案

解决方案很简单:修改getStepDataJson()函数,让它只在确认是AJAX请求时才直接输出JSON并退出:

/*** 获取步数JSON数据,用于AJAX请求*/
public function getStepDataJson()
{$history = $this->getStepHistory();$stats = $this->getStepStats();$data = ['history' => $history,'stats' => $stats];// 只在AJAX请求时才直接输出JSON并退出if (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {header('Content-Type: application/json');echo json_encode($data);exit;}// 如果不是AJAX请求,返回数据而不直接输出return $data;
}

这个改进添加了一个检查机制,通过判断$_SERVER['HTTP_X_REQUESTED_WITH']是否为xmlhttprequest来确定当前是否是一个AJAX请求。如果是,才执行原来的行为;如果不是,则只返回数据而不直接输出。

技术要点

  1. AJAX请求的识别:通常AJAX请求会包含X-Requested-With: XMLHttpRequest头,这是检测AJAX请求的标准方法。

  2. 避免直接输出:在MVC架构的应用中,控制器方法通常不应该直接输出内容,而是返回数据让框架处理。

  3. 避免无条件退出exitdie会立即终止PHP的执行,应谨慎使用,尤其是在可能被其他代码调用的函数中。

教训与最佳实践

在开发PHP插件或组件时,应遵循以下原则:

  1. 关注点分离:数据处理与输出应该分开,不要在获取数据的函数中直接输出。

  2. 条件性输出:如果必须在函数中输出,应该有明确的条件控制。

  3. 防御性编程:总是假设你的函数可能在意外的情况下被调用,添加适当的检查。

  4. 明确文档:清晰记录函数的行为和副作用,特别是那些会改变HTTP头或直接输出的函数。

这个简单的修改解决了首页显示JSON数据的问题,也提醒我们在插件开发中要注意代码的健壮性和兼容性。


作者:xuan
个人博客:https://blog.ybyq.wang
原文链接:https://blog.ybyq.wang/archives/770.html
欢迎访问我的博客,获取更多技术文章和教程。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/bicheng/90692.shtml
繁体地址,请注明出处:http://hk.pswp.cn/bicheng/90692.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

落霞归雁的思维框架:十大经典思维工具的源头活水

在当今复杂多变的世界中&#xff0c;思维框架成为了解决问题、优化决策和提升效率的重要工具。提到思维框架&#xff0c;人们往往会想到那些被广泛认可和应用的十大经典思维工具&#xff1a;金字塔原理、黄金圈法则、5W1H分析法、SWOT分析、SCQA模型、STAR法则、PDCA循环、六顶…

spring Could 高频面试题

一、基础概念Spring Cloud 的核心组件有哪些&#xff1f; 答案&#xff1a;Eureka/Nacos&#xff08;服务注册发现&#xff09;、Ribbon/LoadBalancer&#xff08;负载均衡&#xff09;、Feign/OpenFeign&#xff08;声明式HTTP客户端&#xff09;、Hystrix/Sentinel&#xff0…

从零开始的云计算生活——番外6,使用zabbix对中间件监控

目录 一.网络设备监控 1、GNS模拟器的使用 创建路由 创建交换机 2.构建网络 3.添加Cisco路由器的监控 二.中间件监控 1、MySQL数据库监控 1.1、拷贝自定义的监控脚本到指定目录 1.2、添加监控用户 1.3、重启zabbix-agent服务 1.4、在zabbix-server服务端测试数据 1…

haproxy七层均衡

一.haproxy的安装和服务信息1.1实验环境ip实验设备172.25.254.100haproxy172.25.254.10RS1172.25.254.20RS2172.25.254.111client1.2软件安装及配置haproxy主机上配置#下载#进入此文件进行编辑#关闭防火墙RS1主机上配置#下载#生成默认文件#重启#关闭防火墙RS2主机上配置#下载#生…

分类预测 | MATLAB实现CPO-SVM冠豪猪算法优化支持向量机分类预测

分类预测 | MATLAB实现CPO-SVM冠豪猪算法优化支持向量机分类预测 目录 分类预测 | MATLAB实现CPO-SVM冠豪猪算法优化支持向量机分类预测 分类效果 基本介绍 算法步骤 参数设定 运行环境 应用场景 程序设计 参考资料 分类效果 基本介绍 该MATLAB代码实现了基于冠豪猪优化算法(…

【MySQL 数据库】MySQL基本查询(第二节)

文章目录&#x1f4dd;Update&#x1f309; 将孙悟空同学的数学成绩变更为 80 分&#x1f309; 将曹孟德同学的数学成绩变更为60分&#xff0c;语文成绩变更为70分&#x1f309; 将总成绩倒数前三的3位同学的数学成绩加上30分&#x1f309;将所有同学的语文成绩更新为原来的2倍…

Axios 响应拦截器

1.定义&#xff1a;响应拦截器&#xff08;Response Interceptor&#xff09;是一个可以在 axios 接收到服务器响应后&#xff0c;响应数据交给 .then() 处理之前执行的函数。你可以用它来统一处理响应数据&#xff0c;进行错误处理&#xff0c;或者对返回的数据做格式化和转换…

k8s的nodeport和ingress

1.流量转发图targerport转发到实际的容器端口containerPort&#xff08;后端端口&#xff09;nodeportingress2.配置场景总结字段作用对象必填示例值何时配置containerPort容器否80需明确记录容器端口时&#xff08;推荐&#xff09;targetPortPod是80定义 Service 转发规则时p…

VLA:自动驾驶的“新大脑”?

&#x1f525; 什么是 VLA&#xff1f;为什么突然火了&#xff1f;在自动驾驶圈子里&#xff0c;最近一个词特别火&#xff1a;VLA。它不是某个新车的型号&#xff0c;也不是某家公司的新品牌&#xff0c;而是一种全新的智能架构&#xff0c;被称为“自动驾驶的大脑2.0”。&…

Linux操作系统之线程(八):信号量sem

前言&#xff1a;大家好啊&#xff0c;我们上一篇文章已经讲解了关于线程同步的一种办法&#xff1a;运用条件变量cond。今天&#xff0c;我们就来学习一下线程同步的另外一种方法&#xff0c;信号量&#xff01;&#xff01;信号量呢有System V 信号量与POSIX 信号量&#xff…

【RocketMQ】一分钟了解RocketMQ

MQ是什么 MQ全称为Message Queue&#xff0c;即消息队列 &#xff0c;是一种提供消息队列服务的中间件&#xff0c;也称为消息中间件&#xff0c;是一套提供了消息生 产、存储、消费全过程的软件系统&#xff0c;遵循FIFO原则。 MQ的好处有哪些 异步解耦 最常见的一个场景是…

01 01 01 第一部分 C++编程知识 C++入门 第一个C++程序

第一部分 C编程知识第一章 C入门 —— 第一个C程序一、第一个C程序代码展示//写一个C程序&#xff0c;实现在屏幕上打印 “hello world” #include <iostream> using namespace std; int main() {cout << "hello world" << endl;return 0; }二、…

进制定义与转换详解

文章目录&#x1f4d8; 进制定义与转换详解一、进制的含义二、常见进制介绍1. 十进制&#xff08;Decimal&#xff0c;Base-10&#xff09;2. 二进制&#xff08;Binary&#xff0c;Base-2&#xff09;3. 八进制&#xff08;Octal&#xff0c;Base-8&#xff09;4. 十六进制&am…

【安卓笔记】用MVC、MVP、MVVM来实现井字棋案例

0. 环境&#xff1a;电脑&#xff1a;Windows10Android Studio: 2024.3.2编程语言: JavaGradle version&#xff1a;8.11.1Compile Sdk Version&#xff1a;35Java 版本&#xff1a;Java111. 首先、简单实现井字棋的功能。功能拆解&#xff1a;1. 棋盘为3x32. 点击棋盘button&a…

【洛谷】单向链表、队列安排、约瑟夫问题(list相关算法题)

文章目录单向链表题目描述题目解析代码队列安排题目描述题目解析代码约瑟夫问题题目描述题目解析代码单向链表 题目描述 题目解析 这道题因为有大量的任意位置插入删除&#xff0c;所以肯定不能用数组&#xff0c;用链表是最合适的&#xff0c;而在算法竞赛通常都用静态链表&a…

当人机交互迈向新纪元:脑机接口与AR/VR/MR的狂飙之路

从手机到 “头盔”&#xff1a;交互终端的变革猜想​​在当今数字化时代&#xff0c;智能手机无疑是我们生活中不可或缺的一部分。它集通讯、娱乐、办公等多种功能于一身&#xff0c;成为了人们与外界交互的主要窗口。然而&#xff0c;随着科技的飞速发展&#xff0c;智能手机作…

InfluxDB HTTP API 接口调用详解(二)

实际应用案例演示 1. 数据写入案例 假设在一个物联网设备数据采集场景中&#xff0c;有多个传感器设备持续采集环境的温度和湿度数据。我们以 Python 语言为例&#xff0c;使用requests库来调用 InfluxDB 的 Write 接口将数据写入 InfluxDB。 首先&#xff0c;确保已经安装了…

世运会线上知识竞赛答题pk小程序怎么做

随着2025年成都世界运动会的来临&#xff0c;越来越多的企事业单位组织员工进行线上知识竞赛&#xff0c;那么答题PK小程序该怎么做&#xff0c;接下来我们来一一分析&#xff1a; 世运会线上知识竞赛答题pk小程序怎么做一、答题功能&#xff1a;支持多种题型&#xff0c;如选择…

Java毕业设计 | 基于微信小程序的家校互动作业管理系统(Spring Boot+Vue.js+uni-app+AI,附源码+文档)

Java毕业设计 | 基于微信小程序的家校互动作业管理系统&#xff08;Spring BootVue.jsuni-app&#xff0c;附源码文档&#xff09;&#x1f3af; 毕业设计私人教练 专注计算机毕设辅导第 6 年&#xff0c;累计 1v1 带飞 800 同学顺利通关。从选题、开题、代码、论文到答辩&…

CentOS8 使用 Docker 搭建 Jellyfin 家庭影音服务器

CentOS8 使用 Docker 搭建 Jellyfin 家庭影音服务器 一、前言 由于 Jellyfin 的 GPL 协议和 Intel 的 media-driver (iHD) Linux 驱动&#xff08;部分开源&#xff09;在协议上不兼容的缘故&#xff0c;Jellyfin 官方的 Docker 镜像&#xff1a;jellyfin/jellyfin 并不包含 …