如何使用原生fetch(Ajax)获取PHP脚本返回的数组数据
问题排查与修复方案
你拿不到后端返回值的问题来自前后端两端的代码错误,分别修正即可:
核心错误点
- 前端逻辑错误:
fetchAPI不会自动把响应内容填充到你自定义的formData对象上,你必须手动读取fetch返回的Response对象才能拿到后端输出的内容,原代码里注释的formData.responseText是jQuery时代的写法,在fetch里完全不适用。 - 后端逻辑错误:原PHP代码的分支写反了,只有文件移动失败的时候才会执行CSV读取;同时逐行
print json_encode($data)会输出多段零散的JSON字符串,前端无法直接解析为合法的结构化数据;另外还存在函数拼写错误、代码块未闭合的语法问题。
修正后的后端代码(file_ingest.php)
逻辑调整点:
- 上传成功后再读取解析CSV
- 所有CSV行统一存入结果数组,一次性输出标准JSON格式
- 加上JSON响应头,避免前端解析乱码
- 补全语法闭合,修正拼写错误
<?php set_time_limit(120); // 初始化返回结果结构 $response = [ 'code' => 0, 'msg' => '', 'data' => [] ]; $filename = $_FILES['file']['name']; $location = "uploads/".$filename; if (move_uploaded_file($_FILES['file']['tmp_name'], $location)) { $response['msg'] = '文件上传成功'; // 上传成功再读取CSV $CSVfp = fopen($location, "r"); if($CSVfp !== FALSE) { // 如果需要跳过表头,可以在这里先执行一次fgetcsv // $header = fgetcsv($CSVfp, 1000, ","); while(!feof($CSVfp)) { $row = fgetcsv($CSVfp, 1000, ","); // 过滤空行 if(!empty($row)) { $response['data'][] = $row; } } fclose($CSVfp); $response['code'] = 1; } else { $response['msg'] = '文件读取失败'; } } else { $response['msg'] = '文件上传失败'; } // 输出JSON头,返回结构化结果 header('Content-Type: application/json; charset=utf-8'); echo json_encode($response, JSON_UNESCAPED_UNICODE); exit; ?>
修正后的前端代码
逻辑调整点:
- 接收fetch返回的Response对象,调用
.json()方法解析后端返回的JSON数据 - 加上状态判断,上传/解析失败时给出对应提示
- 拿到
data数组后可以直接用来渲染页面表格/其他内容
<!DOCTYPE html> <html> <head> <style> .table_class{ display:none; } </style> </head> <body> <input id="fileupload" type="file" name="fileupload" /> <button id="upload-button" onclick="uploadFile()"> Upload </button> <p id="test"></p> <!-- 用来展示CSV数据的容器 --> <div id="csv-container"></div> <script> async function uploadFile() { const fileDom = document.getElementById("fileupload"); const testDom = document.getElementById("test"); const containerDom = document.getElementById("csv-container"); if(!fileDom.files[0]) { testDom.innerText = '请先选择要上传的文件'; return; } let formData = new FormData(); formData.append("file", fileDom.files[0]); try { const res = await fetch('file_ingest.php', { method: "POST", body: formData, }); // 解析后端返回的JSON const result = await res.json(); console.log('后端返回完整结果:', result); if(result.code === 1) { testDom.innerText = '文件上传并解析成功,共读取到' + result.data.length + '行数据'; // 在这里处理result.data,也就是后端传过来的CSV数组,示例为渲染表格 let tableHtml = '<table border="1" cellpadding="6" cellspacing="0">'; result.data.forEach(row => { tableHtml += '<tr>'; row.forEach(cell => { tableHtml += `<td>${cell ?? ''}</td>`; }) tableHtml += '</tr>'; }) tableHtml += '</table>'; containerDom.innerHTML = tableHtml; } else { testDom.innerText = '处理失败:' + result.msg; } } catch (err) { console.error('请求出错:', err); testDom.innerText = '请求发生错误,请检查网络或服务端配置'; } } </script> </body> </html>
补充说明
fetch API获取响应内容的常用方法对应不同的返回格式:
- 后端返回JSON:用
await response.json()直接拿到解析后的JS对象/数组 - 后端返回纯文本/HTML:用
await response.text()拿到字符串 - 后端返回二进制文件(图片/压缩包等):用
await response.blob()拿到Blob对象
内容的提问来源于stack exchange,提问作者Weston Simon
相关产品推荐
相关产品推荐

