如何在不使用 JQuery 的情况下使用 fetch API 以 JSON 格式发布表单数据?

Posted

技术标签:

【中文标题】如何在不使用 JQuery 的情况下使用 fetch API 以 JSON 格式发布表单数据?【英文标题】:How can I POST a form data in JSON format using fetch API without using JQuery? 【发布时间】:2021-01-07 15:26:41 【问题描述】:

我是 javascript 和使用 API 的新学生。作为练习的一部分,我正在构建一个带有简单表单的页面来收集电子邮件地址。

我的页面有四个组件——一个 html 表单、一个处理表单提交事件的函数、将表单数据 POST 到 JSON 的代码,以及收集电子邮件的 API。

请参阅下面的代码。当我测试页面时,它一直给我 500 内部错误,我无法确定哪一部分是错误的。

    API

我没有这方面的代码库,但它的作用是使用 POST 收集电子邮件地址。 POST 必须以 JSON 格式完成,并且必须具有以下两个属性:

"email": "aaa@aa.com","source": "website-name"

    HTML 表单

此表格仅收集电子邮件地址。

    <div class="mx-auto">
      <form class="form" name="form_head" id="form_head">
        <div class="form-row">
          <div class="mb-md-3">
            <input type="email" name="email" id="email" class="form-control" placeholder="Enter your email">
          </div>
          <div class="md-3">
            <button type="submit" class="btn">Submit</button>
          </div>
        </div>
      </form>
    </div>

    获取

     <script>
     // To POST form data as JSON with fetch
    
     async function postFormDataAsJson( url, formData ) 
       const formDataJsonString = JSON.stringify(formData);
    
       const fetchOptions = 
         method: "POST",
         headers: 
           "Content-Type": "application/json",
           "Accept": "application/json",
         ,
         body: formDataJsonString
       ;
    
       const response = await fetch(url, fetchOptions);
    
       if (!response.ok) 
         const errorMessage = await response.text();
         throw new Error(errorMessage);
       
    
       return response.json();
     
    

    事件处理函数

     // Event handler for a form submit event
    
     async function handleFormSubmit(e) 
       e.preventDefault();
    
       const form = e.currentTarget;
       const url = /*"API url from #1"*/;
    
       try 
         const formData = new FormData(form);
         formData.append('"source"','"website-name"');
    
         /* Instead of above, I also tried below but didn't work:
          const formData = 
            "email": `$form.name`,
            "source": "website-name"
           */
    
         const responseData = await postFormDataAsJson( url, formData );
    
         console.log( responseData );
        catch (error) 
         console.error(error);
       
     
    
    
     const formHead = document.getElementById('form_head');
     formHead.addEventListener('submit', handleFormSubmit);
    

我觉得#4 事件处理函数中const formData = new FormData(form) 的结果可能不是Object 的正确形式,因为当我使用const formData = "email": "aaa@aa.com", "source": "website-name" 等假对象尝试相同的函数时,页面按预期工作。

我个人更喜欢在不使用 JQuery 的情况下尽可能多地解决此问题的方法,但我们将不胜感激任何建议。提前感谢您的 cmets!

【问题讨论】:

【参考方案1】:

FormData 不创建常规对象,而是创建不公开其值的可迭代对象。您只能通过使用for...of 循环或使用get()getAll() 方法从FormData 实例获取值。

所以如果你真的需要 JSON,那么你应该编写一个辅助函数来创建一个对象,循环遍历 FormData 实例并将对象中的键分配给它对应的值。

然后返回字符串化的结果,你就得到了一些 JSON。

const formDataToJSON = formData => 
  if (!(formData instanceof FormData)) 
    throw TypeError('formData argument is not an instance of FormData');
  

  const data = 
  for (const [name, value] of formData) 
    data[name] = value;
  

  return JSON.stringify(data);

async function postFormDataAsJson( url, formData ) 
   const formDataJsonString = formDataToJSON(formData);
   ...

注意:formData 对象包含BlobFile 等复杂值时,这不起作用。

【讨论】:

谢谢@Emiel。虽然我有点挣扎,但它有很大帮助。我接受了您的评论并将 formDataToJson 的变量设为空白,然后在正文中以 formDataToJson() 的形式运行该函数并且它起作用了。【参考方案2】:

Formdata 与 JSON 数据不同。 Formdata 内容类型为multipart/form-data。如果不需要上传文件,就不需要Formdata,用JSON就够了

【讨论】:

以上是关于如何在不使用 JQuery 的情况下使用 fetch API 以 JSON 格式发布表单数据?的主要内容,如果未能解决你的问题,请参考以下文章

如何在不使用 jquery append 的情况下插入元标记?

如何在不使用 jQuery(替代方式)的情况下知道页面何时准备就绪? [复制]

如何在不使用插件的情况下将 jQuery 1.5.1 升级到 3.0

如何在不使用 jquery 插件的情况下快速跳转到下一部分?

如何在不使用jQuery的情况下获取元素的offset()。top值?

如何使用 jquery 在不丢失样式和插件(select2)的情况下刷新 div