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



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

我个人更喜欢一种尽可能不使用JQuery的方法来解决这个问题,但任何建议都将不胜感激。提前感谢您的评论!

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(时,此操作不起作用。

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

最新更新