Fetch API로 양식 데이터를 게시하려면 어떻게합니까?


116

내 코드 :

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--

(전송할 때마다 경계의 숫자가 변경되는 이유를 모르겠습니다 ...)

"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 () (jQuery를 사용하지 않고) 또는 컨트롤러에서 mulitpart / form-data를 디코딩하는 방법입니다. 그래도 답변 주셔서 감사합니다.


사용과 관련된 문제는 무엇입니까 FormData?
guest271314

1
"email=test@example.com&password=pw"로 게시하고 싶습니다. 가능할까요?

1
“경계 번호가 전송 될 때마다 변경되는 이유를 모르겠습니다…” – 경계 식별자는 임의의 식별자 일 뿐이며 그 자체로는 의미가 없습니다. 따라서 여기서 임의의 숫자를 선택하는 것은 잘못된 것이 아닙니다 (클라이언트가 일반적으로 수행하는 작업).
찌를

답변:


149

MDNFormData 을 인용하려면 (강조 내) :

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));

그래도 브라우저에서 일부 실험적인 지원이 있으므로 사용하기 전에 제대로 테스트해야합니다.


18
객체를 사용하거나 FormData루프 대신 생성자에서 직접 사용할 수도 있습니다 .new URLSearchParams(new FormData(formElement))
monk-time

@ monk-time 그 답변을 작성할 당시에 생성자 인수 URLSearchParams매우 새롭고 지원이 매우 제한적이었습니다.
찌르기

3
죄송합니다. 불만이 아닙니다. 앞으로이 글을 읽으 실 모든 분들께 드리는 메모입니다.
monk-time

1
@Prasanth 콘텐츠 유형을 직접 명시 적으로 지정할 수 있지만 올바른 유형을 선택해야 합니다 . 그냥 놔두고 fetch당신을 위해 돌보는 것이 더 쉽습니다 .
찌를

1
@chovy URLSearchParams는 대부분의 최신 브라우저에 전역 개체로 내장되어 있으며 Node.js 에서도 작동합니다.
찌르기

67

고객

컨텐츠 유형 헤더를 설정하지 마십시오.

// 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; }
}

4
이것이 작동하는 동안 이것은 application/x-www-form-urlencodedOP가 요구 하는 데이터를 보내지 않습니다 .
찌르기

5
나를 위해 헤더에서 제거 Content-Type 하고 브라우저가 자동으로 수행하도록 할 때 작동했습니다 . 감사!
Chris

감사합니다 @regnauld가 하루 종일이 문제를 해결하려고 노력했습니다!
ak85

1
Fetch에 대해 'Content-type'을 설정하지 않으면 multipart/form-data양식 데이터를 위해 있어야하는 으로 설정됩니다 ! 그런 다음 multerexpressjs에서 사용 하여 해당 데이터 형식을 쉽게 구문 분석 할 수 있습니다.
kyw

23

인수로 전달 된 쿼리 문자열 bodyURLSearchParams사용 하여의 인스턴스로 설정할 수 있습니다.

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>


2
Reflect.apply(params.set, params, props)특히 읽을 수없는 말입니다 params.set(props[0], props[1]).
찌르기

@poke Reflect.apply(params.set, params, props)는 여기서 관점에서 읽을 수 있습니다.
guest271314

이것이 유일한 답인 것 같습니다 : / 감사합니다! :)
OZZIE

0

FormData및 사용 하여 fetch데이터 수집 및 전송


0
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"
  });
 }

7
코드 전용 답변은 일반적으로 작동 방식과 이유에 대한 설명을 추가하여 개선 할 수 있습니다. 기존 답변과 함께 2 년 된 질문에 대한 답변을 추가 할 때 답변에서 다루는 질문의 새로운 측면을 지적하는 것이 중요합니다.
Jason Aller
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.