我的代码:
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的方法。谢谢你的答案。
答案 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)
使用FormData
和fetch
抓取并发送数据
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"
});
}