मल्टीपर्ट फार्म डेटा के साथ पोस्ट प्राप्त करें


86

मैं इस तरह एक URL ला रहा हूं:

fetch(url, {
  mode: 'no-cors',
  method: method || null,
  headers: {
    'Accept': 'application/json, application/xml, text/plain, text/html, *.*',
    'Content-Type': 'multipart/form-data'
  },
  body: JSON.stringify(data) || null,
}).then(function(response) {
  console.log(response.status)
  console.log("response");
  console.log(response)
})

मेरा एपीआई डेटा की अपेक्षा करता है कि multipart/form-dataमैं content-typeइस प्रकार का उपयोग कर रहा हूं ... लेकिन यह मुझे स्थिति कोड 400 के साथ प्रतिक्रिया दे रहा है।

मेरे कोड में क्या गलत है?

जवाबों:


163

आप होने की सेटिंग कर Content-Typeरहे हैं multipart/form-data, लेकिन फिर JSON.stringifyशरीर डेटा पर उपयोग कर रहे हैं , जो वापस लौटता है application/json। आपके पास एक सामग्री प्रकार बेमेल है।

आपको multipart/form-dataइसके बजाय अपने डेटा को एनकोड करना होगा json। आमतौर पर multipart/form-dataफ़ाइलों को अपलोड करते समय उपयोग किया जाता है, और application/x-www-form-urlencoded(HTML प्रपत्रों के लिए डिफ़ॉल्ट) की तुलना में थोड़ा अधिक जटिल है ।

के लिए विनिर्देश RFC 1867multipart/form-data में पाया जा सकता है ।

जावास्क्रिप्ट के माध्यम से उस तरह के डेटा को कैसे सबमिट किया जाए, इस पर एक गाइड के लिए, यहां देखें ।

मूल विचार फ़ॉर्मडैट ऑब्जेक्ट (IE <10 में समर्थित नहीं) का उपयोग करना है:

async function sendData(url, data) {
  const formData  = new FormData();

  for(const name in data) {
    formData.append(name, data[name]);
  }

  const response = await fetch(url, {
    method: 'POST',
    body: formData
  });

  // ...
}

प्रति इस लेख मेकअप यकीन नहीं स्थापित करने के लिए Content-Typeशीर्ष लेख। ब्राउज़र आपके लिए इसे boundaryपैरामीटर सहित सेट करेगा ।


const fd = new FormData (); // फाइल अपलोड करने के लिए। fd.append ('फ़ाइल', fileToUpload); fd.append ('jsondatakey', 'jsondatavalue'); इससे आप बॉडी में कुछ जसन डेटा के साथ फाइल भेज पाएंगे।
ज्ञान

25

मैं हाल ही में IPFS के साथ काम कर रहा था और यह काम किया। फ़ाइल अपलोड करने के लिए IPFS के लिए एक कर्ल उदाहरण इस तरह दिखता है:

curl -i -H "Content-Type: multipart/form-data; boundary=CUSTOM" -d $'--CUSTOM\r\nContent-Type: multipart/octet-stream\r\nContent-Disposition: file; filename="test"\r\n\r\nHello World!\n--CUSTOM--' "http://localhost:5001/api/v0/add"

मूल विचार है कि प्रत्येक भाग (में स्ट्रिंग द्वारा विभाजित है boundaryके साथ --) अपने आप हेडर है ( Content-Type, दूसरे भाग में, उदाहरण के लिए।) FormDataवस्तु, आप के लिए यह सब का प्रबंधन करता है, तो यह एक बेहतर तरीका हमारे लक्ष्यों को पूरा करने के लिए।

यह एपीआई को इस तरह लाने के लिए अनुवाद करता है:

const formData = new FormData()
formData.append('blob', new Blob(['Hello World!\n']), 'test')

fetch('http://localhost:5001/api/v0/add', {
  method: 'POST',
  body: formData
})
.then(r => r.json())
.then(data => {
  console.log(data)
})

16
उपरोक्त विधि के बारे में ध्यान दें, हेडर की आपूर्ति न करें यदि आप इसे फॉर्मडाटा का उपयोग करते हैं क्योंकि यह सीमाएं स्वतः ही सेट हो जाएगी।
मैट पेंग्ली

1
धन्यवाद @MattPengelly! कस्टम हेडर को प्राधिकरण की तरह कैसे सेट करें?
ड्रैगोस स्ट्रुगर

7
@DragosStrugar आप अभी भी हेडर सेट कर सकते हैं (प्राधिकरण शामिल है), यदि आप फॉर्मडाटा का उपयोग कर रहे हैं तो बस सामग्री-प्रकार हेडर को मैन्युअल रूप से सेट न करें।
रॉबर्टमैकेड

2
यदि यह फ़ॉर्मडैट का उपयोग कर रहा है तो 'सामग्री-प्रकार' के साथ हेडर की आपूर्ति न करें।
caot

1
कर्ल उदाहरण में, आपको इसकी आवश्यकता है। में FormDataउदाहरण के लिए, यह आवश्यक नहीं ब्राउज़र आप के लिए है कि शीर्ष लेख भेजता है और यह भी सभी माइम-boundries है, जो इस समाधान की बात है का प्रबंधन करता है क्योंकि है।
कोन्सुमेर
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.