You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用原生fetch(Ajax)获取PHP脚本返回的数组数据

问题排查与修复方案

你拿不到后端返回值的问题来自前后端两端的代码错误,分别修正即可:

核心错误点

  • 前端逻辑错误:fetch API不会自动把响应内容填充到你自定义的formData对象上,你必须手动读取fetch返回的Response对象才能拿到后端输出的内容,原代码里注释的formData.responseText是jQuery时代的写法,在fetch里完全不适用。
  • 后端逻辑错误:原PHP代码的分支写反了,只有文件移动失败的时候才会执行CSV读取;同时逐行print json_encode($data)会输出多段零散的JSON字符串,前端无法直接解析为合法的结构化数据;另外还存在函数拼写错误、代码块未闭合的语法问题。

修正后的后端代码(file_ingest.php)

逻辑调整点:

  1. 上传成功后再读取解析CSV
  2. 所有CSV行统一存入结果数组,一次性输出标准JSON格式
  3. 加上JSON响应头,避免前端解析乱码
  4. 补全语法闭合,修正拼写错误
<?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;
?>

修正后的前端代码

逻辑调整点:

  1. 接收fetch返回的Response对象,调用.json()方法解析后端返回的JSON数据
  2. 加上状态判断,上传/解析失败时给出对应提示
  3. 拿到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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 23:45:45