如何使用fetch api发布表单数据?

时间:2017-10-09 06:27:18

标签: javascript fetch-api

我的代码:

fetch("api/xxx", {
    body: new FormData(document.getElementById("form")),
    headers: {
        "Content-Type": "application/x-www-form-urlencoded",
        // "Content-Type": "multipart/form-data",
    },
    method: "post",
}

我尝试使用fetch api发布我的表单,它发送的正文如下:

-----------------------------114782935826962
Content-Disposition: form-data; name="email"

test@example.com
-----------------------------114782935826962
Content-Disposition: form-data; name="password"

pw
-----------------------------114782935826962--

(我不知道为什么每次发送时边界数都会改变......)

我希望用#34; Content-Type":" application / x-www-form-urlencoded"发送数据,我该怎么办?或者,如果我只需处理它,我如何解码控制器中的数据?

对谁回答我的问题,我知道我可以做到:

fetch("api/xxx", {
    body: "email=test@example.com&password=pw",
    headers: {
        "Content-Type": "application/x-www-form-urlencoded",
    },
    method: "post",
}

我想要的是像$("#form")。jQuery中的serialize()(没有使用jQuery)或者在控制器中解码mulitpart / form-data的方法。谢谢你的答案。

9 个答案:

答案 0 :(得分:67)

引用MDN on FormData(强调我的):

  

FormData 界面提供了一种轻松构建表示表单字段及其值的键/值对的方法,然后可以使用XMLHttpRequest.send()轻松发送方法。 如果编码类型设置为"multipart/form-data" ,则表单使用的格式相同。

因此,在使用FormData时,您将自己锁定在multipart/form-data。无法发送FormData对象作为正文,而multipart/form-data格式发送数据。

如果要将数据作为application/x-www-form-urlencoded发送,则必须将主体指定为URL编码的字符串,或者传递URLSearchParams对象。遗憾的是,后者无法从form元素直接初始化。如果您不想自己遍历表单元素( 可以使用HTMLFormElement.elements执行),您还可以从URLSearchParams创建FormData对象对象:

const data = new URLSearchParams();
for (const pair of new FormData(formElement)) {
    data.append(pair[0], pair[1]);
}

fetch(url, {
    method: 'post',
    body: data,
})
.then(…);

请注意,您无需自己指定Content-Type标题。

正如评论中monk-time所述,您还可以创建URLSearchParams并直接传递FormData对象,而不是将值附加到循环中:

const data = new URLSearchParams(new FormData(formElement));

这仍然在浏览器中有一些实验支持,因此请确保在使用之前对其进行正确测试。

答案 1 :(得分:25)

<强>客户端

不要设置内容类型标题。

// Build formData object.
let formData = new FormData();
formData.append('name', 'John');
formData.append('password', 'John123');

fetch("api/SampleData",
    {
        body: formData,
        method: "post"
    });

服务器

使用FromForm属性指定绑定源是表单数据。

[Route("api/[controller]")]
public class SampleDataController : Controller
{
    [HttpPost]
    public IActionResult Create([FromForm]UserDto dto)
    {
        return Ok();
    }
}

public class UserDto
{
    public string Name { get; set; }
    public string Password { get; set; }
}

答案 2 :(得分:8)

您可以将body设置为URLSearchParams的实例,并将查询字符串作为参数传递

fetch("/path/to/server", {
  method:"POST"
, body:new URLSearchParams("email=test@example.com&password=pw")
})

document.forms[0].onsubmit = async(e) => {
  e.preventDefault();
  const params = new URLSearchParams([...new FormData(e.target).entries()]);
  // fetch("/path/to/server", {method:"POST", body:params})
  const response = await new Response(params).text();
  console.log(response);
}
<form>
  <input name="email" value="test@example.com">
  <input name="password" value="pw">
  <input type="submit">
</form>

答案 3 :(得分:5)

事实证明,使用 fetch api,您不必包含标题“Content-type”:“multipart/form-data”。

所以以下工作:

let formData = new FormData()
formData.append("nameField", fileToSend)

fetch(yourUrlToPost, {
   method: "POST",
   body: formData
})

请注意,使用 axios 我必须使用内容类型。

答案 4 :(得分:3)

使用FormDatafetch抓取并发送数据

fetch(form.action, {method:'post', body: new FormData(form)});

function send(e,form) {
  fetch(form.action, {method:'post', body: new FormData(form)});

  console.log('We send post asynchronously (AJAX)');
  e.preventDefault();
}
<form method="POST" action="myapi/send" onsubmit="send(event,this)">
    <input hidden name="crsfToken" value="a1e24s1">
    <input name="email" value="a@b.com">
    <input name="phone" value="123-456-789">
    <input type="submit">    
</form>

Look on chrome console>network before/after 'submit'

答案 5 :(得分:1)

为了添加上面的好答案,您还可以避免在 HTML 中明确设置操作并在 javascript 中使用事件处理程序,使用“this”作为创建“FormData”对象的表单

HTML 格式:

<form id="mainForm" class="" novalidate>
<!--Whatever here...-->
</form>

在你的 JS 中:

$("#mainForm").submit(function( event ) {
  event.preventDefault();
  const formData = new URLSearchParams(new FormData(this));
  fetch("http://localhost:8080/your/server",
    {   method: 'POST',
        mode : 'same-origin',
        credentials: 'same-origin' ,
        body : formData
    })
    .then(function(response) {
      return response.text()
    }).then(function(text) {
        //text is the server's response
    });
});

答案 6 :(得分:1)

?‍?这些可以帮助您:

let formData = new FormData();
            formData.append("name", "John");
            formData.append("password", "John123");
            fetch("https://yourwebhook", {
              method: "POST",
              mode: "no-cors",
              cache: "no-cache",
              credentials: "same-origin",
              headers: {
                "Content-Type": "form-data"
              },
              body: formData
            });
            //router.push("/registro-completado");
          } else {
            // doc.data() will be undefined in this case
            console.log("No such document!");
          }
        })
        .catch(function(error) {
          console.log("Error getting document:", error);
        });

答案 7 :(得分:0)

//写入数据

async function write(param) {
  var zahl = param.getAttribute("data-role");

  let mood = {
    appId: app_ID,
    key: "",
    value: zahl
  };

  let response = await fetch(web_api, {
    method: "POST",
    headers: {
      "Content-Type": "application/json"
    },
    body: JSON.stringify(mood)
  });
  console.log(currentMood);

//获取数据

async function get() {

  let response = await fetch(web_api + "/App/" + app_ID, {
    method: "GET",
    headers: {
      "Content-Typ": "application/jason"
    }
  });

  let todos = await response.json();

//删除数据

function remove(id) {
  return fetch(web_api" + id, {
    method: "DELETE"
  }).then(response => {
    if (!response.ok) {
      throw new Error("Todo konnte nicht entfernt werden.");
    }
  });
}


async function removeAll() {
  let response = await fetch(web_api + "/App/" + app_ID, {
    method: "GET",
    headers: {
      "Content-Typ": "application/jason"
    }
  });
  let todos = await response.json();
  console.log(todos);

  for (let todo of todos) {
    await remove(todo.id);
  }
}

//更新数据

  function updateTodo(todo) {
return fetch(`https://__________________/api/items/${todo.id}`, {
  method: "PUT",
  body: JSON.stringify(todo),
  headers: {
    "Content-Type": "application/json",
  },
}).then((response) => {
  if (!response.ok) {
    throw new Error("Todo konnte nicht upgedated werden.");
  }
});

}

答案 8 :(得分:-1)

要使用获取API发布表单数据, 试试这个代码对我有用^ _ ^

function card(fileUri) {
let body = new FormData();
let formData = new FormData();
formData.append('file', fileUri);

fetch("http://X.X.X.X:PORT/upload",
  {
      body: formData,
      method: "post"
  });
 }