Form verilerini getirme api ile nasıl gönderirim?


118

Kodum:

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

Formumu getirme api'sini kullanarak göndermeye çalıştım ve gönderdiği gövde şuna benziyor:

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

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

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

(Sınırdaki sayının her gönderişinde neden değiştiğini bilmiyorum ...)

Verileri "Content-Type": "application / x-www-form-urlencoded" ile göndermesini istiyorum, ne yapmalıyım? Veya bununla başa çıkmak zorunda kalırsam, denetleyicimdeki verileri nasıl çözebilirim?


Soruma cevap veren kişi, bunu yapabileceğimi biliyorum:

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

İstediğim, jQuery'de $ ("# form"). Serialize () gibi bir şey (jQuery kullanarak) veya denetleyicide mulitpart / form-data kodunu çözme yolu. Yine de cevaplarınız için teşekkürler.


Kullanmanın sorunu nedir FormData?
misafir271314

1
"Email=test@example.com&password=pw" olarak göndermek istiyorum. Mümkün mü?
Zack

1
"Sınırdaki sayının her gönderişinde neden değiştiğini bilmiyorum…" - Sınır tanımlayıcı sadece rastgele bir tanımlayıcıdır, herhangi bir şey olabilir ve kendi başına bir anlamı yoktur. Dolayısıyla, orada rastgele bir sayı seçmenin yanlış bir tarafı yoktur (bu, müşterilerin genellikle yaptığı şeydir).
dürtmek

Yanıtlar:


149

MDN'denFormData alıntı yapmak için (vurgu benim):

FormDataArayüzü kolayca form alanları ve daha sonra kolayca kullanılarak gönderilebilir değerlerini temsil eden anahtar / değer çiftleri kümesini oluşturmak için bir yol sağlar XMLHttpRequest.send()yöntem. Kodlama türü ayarlanırsa bir formun kullanacağı formatı kullanır"multipart/form-data" .

Yani kullanırken FormDatakendinizi içine kilitliyorsunuz multipart/form-data. Bir göndermeye yolu yoktur FormDataorganı olarak nesne ve değil de gönderme verileri multipart/form-databiçiminde.

Verileri olduğu gibi göndermek istiyorsanız application/x-www-form-urlencoded, gövdeyi URL kodlu bir dize olarak belirtmeniz veya bir URLSearchParamsnesne iletmeniz gerekir. İkincisi maalesef doğrudan bir formelemandan başlatılamaz . Z (yani form elemanları kendine yinelemenize istemiyorsanız olabilir kullanarak yapmak HTMLFormElement.elements), ayrıca bir yaratabilecek URLSearchParamsbir nesneyi FormDatanesne:

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-TypeKendiniz bir başlık belirtmenize gerek olmadığını unutmayın .


Monk-time tarafından yorumlarda belirtildiği gibi , değerleri bir döngüde eklemek yerine doğrudan nesneyi oluşturabilir URLSearchParamsve iletebilirsiniz FormData:

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

Bu hala tarayıcılarda bazı deneysel desteğe sahiptir, bu yüzden kullanmadan önce bunu doğru bir şekilde test ettiğinizden emin olun.


18
Ayrıca bir nesneyi veya FormDatabir döngü yerine doğrudan new URLSearchParams(new FormData(formElement))
monk-time

Bu cevabı yazma zaman @ keşiş zamanlı, hiç yapıcı argüman URLSearchParamsoldu çok yeni ve çok sınırlı destek almıştı.
dürtmek

3
üzgünüm, bu bir şikayet değildi, sadece bunu gelecekte okuyacak herkese bir not.
keşiş zamanı

1
@Prasanth İçerik türünü kendiniz açıkça belirtebilirsiniz, ancak doğru olanı seçmelisiniz . Onu bırakıp fetchsizin için halletmek daha kolay .
dürtmek

1
@chovy URLSearchParams, çoğu modern tarayıcıda global bir nesne olarak yerleşiktir ve ayrıca Node'dan çalışır.
dürtmek

68

Müşteri

İçerik türü başlığını ayarlamayın.

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

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

Sunucu

FromFormBağlama kaynağının form verileri olduğunu belirtmek için özniteliği kullanın .

[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
Bu çalışırken, bu application/x-www-form-urlencodedOP'nin istediği gibi verileri göndermez .
dürtmek

5
Benim için, başlıktan KALDIRDIĞımda Content-Type ve tarayıcının otomatik olarak yapmasına izin verdiğimde işe yaradı . Teşekkürler!
Chris,

Teşekkürler @regnauld bütün gün bunu çözmeye çalışıyorduk!
ak85

1
Getirme için 'İçerik türünü' ayarlamazsanız, bunu şu şekilde ayarlayacaktır multipart/form-data, form verileri için olması gereken budur! Daha sonra multerbu veri formatını kolayca ayrıştırmak için expressjs'de kullanabilirsiniz .
kyw

23

Bağımsız değişken olarak iletilen sorgu dizesine sahip bodybir örneğe ayarlayabilirsiniz .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>


2
Reflect.apply(params.set, params, props)özellikle okunamayan bir söyleme şeklidir params.set(props[0], props[1]).
dürtmek

@ poke Reflect.apply(params.set, params, props)burada perspektiften okunabilir.
guest271314

Burada işe yarayan tek cevap bu gibi görünüyor: / teşekkür ederim! :)
OZZIE

0

Kullanım FormDatave fetchkapmak ve gönder verilerine


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
Yalnızca kod yanıtları genellikle nasıl ve neden çalıştıklarına ilişkin bazı açıklamalar eklenerek geliştirilebilir. İki yıllık bir soruya mevcut cevaplarla bir cevap eklerken, cevabınızın hitap ettiği sorunun hangi yeni yönünü belirtmek önemlidir.
Jason Aller
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.