我如何 post 使用 fetch api 形成数据?
How do I post form data with 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",
}
我尝试 post 使用 fetch api 我的表单,它发送的正文如下:
-----------------------------114782935826962
Content-Disposition: form-data; name="email"
test@example.com
-----------------------------114782935826962
Content-Disposition: form-data; name="password"
pw
-----------------------------114782935826962--
(不知道为什么boundary里的数字每次发送都变...)
我想用"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",
}
我想要的是 jQuery 中的 $("#form").serialize() (w/o 使用 jQuery)或解码方式 mulitpart/form-data 在控制器中。谢谢你的回答。
您可以将 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>
客户端
不设置 content-type header.
// 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; }
}
引用MDN on FormData
(强调我的):
The FormData
interface provides a way to easily construct a set of key/value pairs representing form fields and their values, which can then be easily sent using the XMLHttpRequest.send()
method. It uses the same format a form would use if the encoding type were set to "multipart/form-data"
.
因此,当您使用 FormData
时,您将自己锁定在 multipart/form-data
中。无法发送 FormData
object 作为 body 和 而不是 以 multipart/form-data
格式发送数据。
如果要将数据作为 application/x-www-form-urlencoded
发送,则必须将 body 指定为 URL-encoded 字符串,或者传递 URLSearchParams
object. The latter unfortunately cannot be directly initialized from a form
element. If you don’t want to iterate through your form elements yourself (which you could do using HTMLFormElement.elements
),您也可以从 FormData
object:
创建 URLSearchParams
object
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
header。
如评论中 monk-time 所述,您还可以创建 URLSearchParams
并直接传递 FormData
object,而不是在循环中附加值:
const data = new URLSearchParams(new FormData(formElement));
尽管浏览器仍对它提供一些实验性支持,因此请务必在使用前对其进行正确测试。
使用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="csrfToken" 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'
到 post 使用 fetch 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"
});
}
要添加上面的好答案,您还可以避免在 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
});
});
这些可以帮到你:
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);
});
使用 fetch api 结果表明您不必包含 headers "Content-type": "multipart/form-data".
因此以下工作:
let formData = new FormData()
formData.append("nameField", fileToSend)
fetch(yourUrlToPost, {
method: "POST",
body: formData
})
请注意,对于 axios,我必须使用 content-type。
@KamilKiełczewski 如果您同意表单数据格式采用表单多部分样式,那么答案很好,但是如果您需要以查询参数样式提交的表单:
You can also pass FormData directly to the URLSearchParams constructor if you want to generate query parameters in the way a would do if it were using simple GET submission.
form = document.querySelector('form')
const formData = new FormData(form);
formData["foo"] = "bar";
const payload = new URLSearchParams(formData)
fetch(form.action, payload)
我的代码:
fetch("api/xxx", {
body: new FormData(document.getElementById("form")),
headers: {
"Content-Type": "application/x-www-form-urlencoded",
// "Content-Type": "multipart/form-data",
},
method: "post",
}
我尝试 post 使用 fetch api 我的表单,它发送的正文如下:
-----------------------------114782935826962
Content-Disposition: form-data; name="email"
test@example.com
-----------------------------114782935826962
Content-Disposition: form-data; name="password"
pw
-----------------------------114782935826962--
(不知道为什么boundary里的数字每次发送都变...)
我想用"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",
}
我想要的是 jQuery 中的 $("#form").serialize() (w/o 使用 jQuery)或解码方式 mulitpart/form-data 在控制器中。谢谢你的回答。
您可以将 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>
客户端
不设置 content-type header.
// 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; }
}
引用MDN on FormData
(强调我的):
The
FormData
interface provides a way to easily construct a set of key/value pairs representing form fields and their values, which can then be easily sent using theXMLHttpRequest.send()
method. It uses the same format a form would use if the encoding type were set to"multipart/form-data"
.
因此,当您使用 FormData
时,您将自己锁定在 multipart/form-data
中。无法发送 FormData
object 作为 body 和 而不是 以 multipart/form-data
格式发送数据。
如果要将数据作为 application/x-www-form-urlencoded
发送,则必须将 body 指定为 URL-encoded 字符串,或者传递 URLSearchParams
object. The latter unfortunately cannot be directly initialized from a form
element. If you don’t want to iterate through your form elements yourself (which you could do using HTMLFormElement.elements
),您也可以从 FormData
object:
URLSearchParams
object
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
header。
如评论中 monk-time 所述,您还可以创建 URLSearchParams
并直接传递 FormData
object,而不是在循环中附加值:
const data = new URLSearchParams(new FormData(formElement));
尽管浏览器仍对它提供一些实验性支持,因此请务必在使用前对其进行正确测试。
使用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="csrfToken" 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'
到 post 使用 fetch 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"
});
}
要添加上面的好答案,您还可以避免在 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
});
});
这些可以帮到你:
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);
});
使用 fetch api 结果表明您不必包含 headers "Content-type": "multipart/form-data".
因此以下工作:
let formData = new FormData()
formData.append("nameField", fileToSend)
fetch(yourUrlToPost, {
method: "POST",
body: formData
})
请注意,对于 axios,我必须使用 content-type。
@KamilKiełczewski 如果您同意表单数据格式采用表单多部分样式,那么答案很好,但是如果您需要以查询参数样式提交的表单:
You can also pass FormData directly to the URLSearchParams constructor if you want to generate query parameters in the way a would do if it were using simple GET submission.
form = document.querySelector('form')
const formData = new FormData(form);
formData["foo"] = "bar";
const payload = new URLSearchParams(formData)
fetch(form.action, payload)