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

使用Giphy API上传GIF出现重复请求与重复存储ID问题求助

问题描述

使用Giphy API实现GIF上传并将返回ID存入localStorage时,首次上传功能正常,但后续每次上传都会发起多次请求,且localStorage中会为每个GIF存入多个ID。

原始代码

HTML

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
  </head>
  <body>
    <form>
      <input type="file" />
      <input type="submit" />
    </form>
    <div class="tree"></div>
    <script src="./fetch-api.js"></script>
  </body>
</html>

JavaScript

const form = document.querySelector('form');
const inputFlie = document.querySelector('input');
const preview = document.querySelector('.tree');
const apiKey = 'yourapikeyhere'

form.addEventListener('change', () => {
  const uploadFile = new FormData();
  uploadFile.append('file', inputFlie.files[0]);

  const heads = {
    method: 'POST',
    api_key: apiKey ,
    body: uploadFile,
  };

  form.addEventListener('submit', async (event) => {
    event.preventDefault();
    try {
      const send = await fetch(
        `https://upload.giphy.com/v1/gifs?api_key=${apiKey}`,
        heads
      );

      const feedback = await send.json();
      if (feedback.meta.status === 200) {
        form.reset();

        uploadID = feedback.data.id;
      }

      if (localStorage.getItem('uploaded') === null) {
        //if we don't create an empty array
        uploadedGifs = [];
        uploadedGifs.push(uploadID);
        localStorage.setItem('uploaded', JSON.stringify(uploadedGifs));
      } else {
        const currentItems = JSON.parse(localStorage.getItem('uploaded'));
        currentItems.push(uploadID);
        localStorage.setItem('uploaded', JSON.stringify(currentItems));
      }

      console.log(feedback);
    } catch (error) {
      console.log(error);
      statusMesage.textContent = 'Something went wrong!';
    }
  });
});
问题原因

核心问题是事件监听嵌套绑定:每次选择文件触发change事件时,都会给表单新增一个submit事件监听器。第一次选文件加1个监听器,第二次选文件再加1个,以此类推。后续点击提交时,所有已绑定的submit监听器都会触发,导致多次请求上传,同时多次往localStorage存入同一个ID。

另外还有两个小问题:

  • uploadID和uploadedGifs未声明,会成为全局变量,可能引发意外问题。
  • FormData在change事件中创建,逻辑上不合理,若用户重复选择文件后提交,可能出现数据不一致的情况。
修复方案

将submit事件监听器移到change事件外部,同时调整FormData的创建时机到submit内部,确保每次提交都使用最新的文件,并且只绑定一次提交事件。

修改后的JavaScript代码:

const form = document.querySelector('form');
const inputFile = document.querySelector('input[type="file"]'); // 更精准的选择器
const preview = document.querySelector('.tree');
const apiKey = 'yourapikeyhere';

// 只绑定一次submit事件
form.addEventListener('submit', async (event) => {
  event.preventDefault();
  
  // 先判断是否选择了文件
  if (!inputFile.files.length) return;

  const uploadFile = new FormData();
  uploadFile.append('file', inputFile.files[0]);

  const options = {
    method: 'POST',
    body: uploadFile,
    // 注意:api_key只需放在URL参数中,无需在请求配置里设置
  };

  try {
    const send = await fetch(
      `https://upload.giphy.com/v1/gifs?api_key=${apiKey}`,
      options
    );

    const feedback = await send.json();
    if (feedback.meta.status === 200) {
      form.reset();
      const uploadID = feedback.data.id;

      // 简化localStorage逻辑
      const uploadedGifs = JSON.parse(localStorage.getItem('uploaded')) || [];
      uploadedGifs.push(uploadID);
      localStorage.setItem('uploaded', JSON.stringify(uploadedGifs));
    }

    console.log(feedback);
  } catch (error) {
    console.log(error);
    // 注意:需提前定义statusMessage元素,否则会报错
    // statusMessage.textContent = '上传出错!';
  }
});
关键修改点
  • 移除change事件监听,直接在submit事件中处理文件获取和上传,避免重复绑定提交监听器。
  • 给uploadID添加const声明,避免全局变量污染。
  • 简化localStorage逻辑:使用JSON.parse(...) || []替代条件判断,代码更简洁。
  • 修正请求配置:Giphy API的api_key只需要放在URL参数中,原代码中的api_key配置项无效。
  • 增加文件选择判断,避免用户未选文件就提交的无效请求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 02:30:58