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

将jQuery AJAX POST请求转为原生JavaScript fetch异步请求时的问题排查与解决咨询

解决原生JavaScript AJAX POST请求的两个问题:JSON解析错误与请求仅执行一次

我来帮你一步步排查并解决这两个问题,都是原生fetch转换时容易踩的坑:


问题1:SyntaxError: Unexpected end of JSON input

这个错误说明fetch尝试解析响应为JSON时失败了,大概率是PHP端的响应格式或响应头有问题。

排查与解决:

  1. 给PHP添加正确的响应头:
    原PHP代码只是直接echo JSON字符串,但没有告诉浏览器这是JSON格式的内容,这会导致fetch的json()方法解析失败。在PHP的echo语句前必须添加:

    header('Content-Type: application/json');
    

    这是关键,确保服务器返回的响应被识别为标准JSON类型。

  2. 检查PHP是否输出了额外内容:
    如果PHP代码有Notice、Warning等错误输出(比如变量未定义),这些文本会附加在JSON前面,直接破坏JSON结构。你可以:

    • 在PHP开头添加error_reporting(0);暂时屏蔽错误输出(上线前建议开启错误日志而非直接输出到页面)
    • 或者先用fetch查看原始响应内容,替换let resultado = await peticion.json();为:
      let rawText = await peticion.text();
      console.log('原始响应内容:', rawText);
      // 之后再尝试解析
      let resultado = JSON.parse(rawText);
      
      这样能直接看到PHP返回的具体内容,快速定位是否有额外输出破坏了JSON格式。

问题2:仅发送一次请求且不更新HTML

你的代码有两个核心逻辑漏洞:

  • 定义了ola处理函数,但从来没有调用它,所以获取到结果后根本没执行更新HTML的逻辑;
  • 只调用了一次envSoli(),没有像原jQuery那样循环发起请求(原代码是每次请求成功后,根据chenille的递增判断是否继续处理下一行)。

修改后的完整代码:

// 实现原jQuery的beforeSend逻辑
const updateCheckStatus = () => {
  const checkStatus = document.getElementById("checkStatus");
  if (checkStatus) {
    checkStatus.innerHTML = "<img src=''/>";
  }
};

const envSoli = async () => {
  // 发起请求前更新状态
  updateCheckStatus();
  
  try {
    let peticion = await fetch("data.php", {
      method: "POST",
      body: `ajax=1&do=check&lista=${encodeURIComponent(leray[chenille])}`,
      headers: {
        "Content-type": "application/x-www-form-urlencoded"
      }
    });

    // 先检查HTTP请求是否成功(状态码200-299)
    if (!peticion.ok) {
      throw new Error(`HTTP错误!状态码:${peticion.status}`);
    }

    let resultado = await peticion.json();
    
    // 调用结果处理函数,传入解析后的JSON数据
    handleResult(resultado);

  } catch (error) {
    console.error('请求出错:', error);
    // 可在此添加用户可见的错误提示逻辑
  }
};

// 抽离结果处理逻辑,更清晰易维护
const handleResult = (oreen) => {
  switch (oreen.enviando) {
    case -1:
      chenille++;
      document.getElementById("div1").innerHTML += oreen.cat + "<br />";
      updateProgress(chenille, leray.length);
      tvmit_wrongUp();
      break;
    case 1:
      chenille++;
      document.getElementById("div1").innerHTML += oreen.dog + "<br />";
      updateProgress(chenille, leray.length);
      tvmit_wrongUp();
      break;
    case 2:
      chenille++;
      document.getElementById("div2").innerHTML += oreen.sky + "<br />";
      nieva++;
      updateProgress(chenille, leray.length);
      tvmit_dieUp();
      break;
    case 3:
      chenille++;
      document.getElementById("div3").innerHTML += oreen.water + "<br />";
      tvmit_liveUp();
      updateProgress(chenille, leray.length);
      break;
  }
  OKTY(leray, chenille, aarsh, nieva);
  
  // 模仿原jQuery的循环逻辑:如果还有未处理的行,继续发起请求
  if (chenille < leray.length) {
    envSoli();
  }
};

// 启动第一个请求
envSoli();

关键修改点说明:

  1. 补充beforeSend逻辑:添加updateCheckStatus函数,实现原jQuery在请求发起前更新状态元素的功能;
  2. 调用结果处理函数:不再定义函数却不执行,确保获取到JSON后立即处理HTML更新;
  3. 增加HTTP状态检查:避免请求失败时静默报错,方便排查服务器端问题;
  4. 实现循环请求:在处理完当前请求后,判断chenille是否小于总行数,若是则再次调用envSoli(),实现逐行发送请求的效果;
  5. 修正HTML追加方式:原生append方法传字符串会变成纯文本节点,改用innerHTML +=实现和jQueryappend一致的HTML追加效果。

内容的提问来源于stack exchange,提问作者SadDeepLoper

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.27 13:42:34