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
英文地址,請注明出處:http://en.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 并不包含 …