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

How can I POST a form data in JSON format using fetch API without using JQuery?

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

我的页面有四个组件 -- HTML 表单、处理表单提交事件的函数、将 POST 表单数据转换为 JSON 的代码,以及收集电子邮件的API。

请看下面的代码。当我测试页面时,它一直给我 500 个内部错误,我无法弄清楚是哪一部分出错了。

  1. API

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

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

  1. 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>
  1. 获取

     <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();
     }
    
  2. 事件处理函数

     // 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) 的结果可能不是正确的对象形式,因为当我使用假对象尝试相同的函数时 const formData = { "email": "aaa@aa.com", "source": "website-name" }页面按预期工作。

我个人更喜欢尽可能不使用 JQuery 来解决此问题的方法,但我们将不胜感激任何建议。预先感谢您的评论!

Formdata 与 JSON 数据不同。表单数据 Content-type 是 multipart/form-data。如果不需要上传文件,就不需要Formdata,用JSON就够了

FormData does not create a regular object, but an iterable object which does not expose its values. You can only get the values from a FormData instance by either looping over it with for...of or by using the get() or getAll() 方法。

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

然后 return 结果字符串化,你得到了一些 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 对象包含像 Blob or File.

这样的复杂值时,这不起作用