通过JS XMLHttpRequest发送JSON字符串丢失内容问题咨询
问题原因
用FormData封装带HTML标签的JSON字符串发送POST请求时,服务器端的安全机制(比如防XSS过滤、自动HTML转义)会把JSON里的<>识别为HTML标签,对其进行转义或截断,导致JSON结构被破坏,出现数组首尾元素合并、HTML标签部分丢失的情况。而Base64编码会把所有特殊字符转成安全的ASCII字符,避开了服务器的过滤规则,所以能正常解析。
解决方案
以下三种方法都能解决这个问题:
1. 直接发送JSON请求体(推荐)
不用FormData封装,直接以application/json格式发送原始JSON字符串,让服务器直接接收完整的JSON内容,避免表单解析时的过滤:
function send_import_form(cmid) { const input = document.getElementById("import_input"); if (input.files.length === 0) { console.log("no files"); } else { const reader = new FileReader(); reader.onload = (e) => { const jsonStr = e.target.result; const url = "import_export_quiz.php"; const request = new XMLHttpRequest(); request.addEventListener("load", function() { console.log(this.response); }); request.open("POST", url); // 设置请求头为JSON类型 request.setRequestHeader("Content-Type", "application/json"); // 直接发送JSON字符串 request.send(jsonStr); }; reader.readAsText(input.files[0]); } }
对应的PHP服务器端处理:
// 读取原始请求体 $jsonStr = file_get_contents('php://input'); // 解析JSON $data = json_decode($jsonStr, true); // 处理后返回示例 echo json_encode($data);
2. 转义JSON中的特殊字符
在客户端把JSON里的<和>转成HTML实体,服务器接收后再转回来:
// 修改FormData部分的代码 const escapedJson = e.target.result.replace(/</g, '<').replace(/>/g, '>'); fdata.append("json", escapedJson);
服务器端PHP处理:
$jsonStr = $_POST['json']; // 把实体转回原始字符 $jsonStr = str_replace(['<', '>'], ['<', '>'], $jsonStr); $data = json_decode($jsonStr, true);
3. 继续使用Base64编码传输
就是你已经验证有效的方法,客户端编码,服务器解码:
// 客户端编码 const base64Json = btoa(e.target.result); fdata.append("json", base64Json);
服务器端PHP处理:
$base64Str = $_POST['json']; // 解码 $jsonStr = base64_decode($base64Str); $data = json_decode($jsonStr, true);
内容的提问来源于stack exchange,提问作者Schleeo
相关产品推荐
相关产品推荐

