FormData.append (“ key”,“ value”) ไม่ทำงาน


107

คุณบอกฉันได้ไหมว่ามีอะไรผิดปกติ:

var formdata = new FormData();
formdata.append("key", "value");
console.log(formdata);

ผลลัพธ์ของฉันเป็นแบบนี้ฉันไม่พบคู่ "คีย์" - "ค่า" ของฉัน

FormData
*__proto__: FormData
**append: function append() { [native code] }
***arguments: null
***caller: null
***length: 0
***name: "append"
***prototype: append
***__proto__: function Empty() {}
*constructor: function FormData() { [native code] }
**arguments: null
**caller: null
**length: 0
**name: "FormData"
**prototype: FormData
**toString: function toString() { [native code] }
*__proto__: Object
**__proto__: Object
**__defineGetter__: function __defineGetter__() { [native code] }
**__defineSetter__: function __defineSetter__() { [native code] }
**__lookupGetter__: function __lookupGetter__() { [native code] }
**__lookupSetter__: function __lookupSetter__() { [native code] }
**constructor: function Object() { [native code] }
**hasOwnProperty: function hasOwnProperty() { [native code] }
**isPrototypeOf: function isPrototypeOf() { [native code] }
**propertyIsEnumerable: function propertyIsEnumerable() { [native code] }
**toLocaleString: function toLocaleString() { [native code] }
**toString: function toString() { [native code] }
**valueOf: function valueOf() { [native code] }

ไม่เข้าใจ! เมื่อวานทำงานได้ดีและวันนี้หัวของฉันกระแทกแป้นพิมพ์หลายครั้ง! Firefox, Chrome เหมือนกันทั้งคู่: /

คำตอบ:


128

ใหม่ใน Chrome 50+ และ Firefox 39+ (การตอบสนอง 44+):

  • formdata.entries()(รวมกับArray.from()เพื่อแก้จุดบกพร่อง)
  • formdata.get(key)
  • และวิธีการที่มีประโยชน์มากขึ้น

คำตอบเดิม:

สิ่งที่ฉันมักจะทำเพื่อ 'debug' FormDataวัตถุเพียงแค่ส่งไป (ที่ใดก็ได้!) และตรวจสอบบันทึกของเบราว์เซอร์ (เช่นแท็บเครือข่ายของ Chrome devtools ')

คุณไม่จำเป็นต้องมี / กรอบ Ajax เดียวกัน คุณไม่ต้องการรายละเอียดใด ๆ เพียงแค่ส่ง:

var xhr = new XMLHttpRequest;
xhr.open('POST', '/', true);
xhr.send(data);

ง่าย.


ขอบคุณ - นี่เป็นวิธีที่รวดเร็วที่มีประโยชน์ในการรับออบเจ็กต์ FormData โดยพิมพ์ลงในคอนโซล Chrome
Dan Smart

ตามวิธีการของ Google formData ถูกเพิ่มใน Chrome v50
thdoan

คุณจะดูบันทึกของเบราว์เซอร์อย่างไรหากเป็นเบราว์เซอร์มือถือเช่น Safari ฉันใช้ออบเจ็กต์ FormData ในเว็บแอปที่มีไว้สำหรับมือถือและไม่สามารถหาวิธีแก้จุดบกพร่องได้
kiwicomb123

1
@ kiwicomb123 Formdata.entries()+ Array.from()+ alert()ถ้ามันทันสมัยพอหรือดูการแก้จุดบกพร่องบนมือถือ
Rudie

ไม่มี edge หรือ ie11?
SuperUberDuper

50

คุณบอกว่ามันใช้ไม่ได้ คุณคาดหวังว่าจะเกิดอะไรขึ้น?

ไม่มีทางที่จะดึงข้อมูลออกจากFormDataวัตถุได้ มีไว้เพื่อให้คุณใช้ในการส่งข้อมูลพร้อมกับXMLHttpRequestวัตถุ (สำหรับsendวิธีการ)

อัปเดตเกือบห้าปีต่อมา: ในเบราว์เซอร์รุ่นใหม่บางตัวสิ่งนี้ไม่เป็นความจริงอีกต่อไปและตอนนี้คุณสามารถดูข้อมูลที่ให้มาFormDataนอกเหนือจากการยัดข้อมูลลงไป ดูคำตอบที่ยอมรับสำหรับข้อมูลเพิ่มเติม


20
โอเค ... นี่มันห่วย เหตุใดฉันจึงไม่สามารถบันทึก FormData ในคอนโซลของฉันได้ :-( สิ่งนี้ไม่สมเหตุสมผลสำหรับฉันเพราะฉันคิดว่ามันเป็นวัตถุทั่วไป
netzaffin

12
@netzaffin: ทั้ง Firebug และตัวตรวจสอบของ Chrome ช่วยให้คุณเห็นพารามิเตอร์คำขอที่ส่งในคำขอ XHR ตราบเท่าที่คุณเปิดแท็บเครือข่ายและเริ่มการบันทึกดังนั้นคุณควรจะสามารถดำเนินการได้ คุณยังสามารถสร้างออบเจ็กต์ wrapper ที่บันทึกฟิลด์และผนวกเข้ากับ FormData จากนั้นตรวจสอบค่านั้น (อย่าลืมส่ง FormData ภายในแทนวัตถุ wrapper)
Jesper

1
อย่างน้อยฉันสามารถตรวจสอบว่าformdataวัตถุมีไฟล์อยู่ข้างในหรือไม่?
MarceloBarbosa

1
@MarceloBarbosa: ดูเหมือนว่าคุณจะไม่ได้รับข้อมูลใด ๆ จากมัน คุณจะต้องเก็บข้อมูลนี้ไว้เอง
Jesper

ตามที่ระบุโดย @Jesper คุณสามารถตรวจสอบคำขอ XHR ที่ส่งในแท็บเครือข่ายของเครื่องมือสำหรับนักพัฒนามีตัวเลือก Params ที่นั่นซึ่งช่วยให้คุณเห็นเนื้อหาของคำขอ POST ที่ส่งไป นอกจากนี้ยังตอบสนอง
Anirudh

23

คุณอาจประสบปัญหาเดียวกันกับที่ฉันพบในตอนแรก ฉันพยายามใช้ FormData เพื่อดึงไฟล์อินพุตทั้งหมดของฉันเพื่ออัปโหลดรูปภาพ แต่ในเวลาเดียวกันฉันต้องการต่อท้ายรหัสเซสชันกับข้อมูลที่ส่งไปยังเซิร์ฟเวอร์ ตลอดเวลานี้ฉันคิดว่าโดยการต่อท้ายข้อมูลคุณจะสามารถเห็นข้อมูลในเซิร์ฟเวอร์ได้โดยการเข้าถึงวัตถุ ฉันผิดไป. เมื่อคุณผนวกเข้ากับ FormData วิธีตรวจสอบข้อมูลที่ต่อท้ายบนเซิร์ฟเวอร์คือการ$_POST['*your appended data*']สืบค้นง่ายๆ ดังนี้:

js:

$('form').submit(function(){
    var sessionID = 8;
    var formData = new FormData(this);
    formData.append('id', sessionID);

    $.ajax({
        url: "yoururl.php",
        data: formData,
        processData: false,
        contentType: false,
        type: 'POST',
        success: function(data){
            alert(data);
        }
    });
});

จากนั้นบน php:

$sessionID = $_POST['id'];
$files = $_FILES['image'];

$foreach ($files as $key=>val){
    //...
}

17

หากคุณอยู่ใน Chrome คุณสามารถตรวจสอบข้อมูลโพสต์

นี่คือวิธีตรวจสอบข้อมูลโพสต์

  1. ไปที่แท็บเครือข่าย
  2. มองหาลิงก์ที่คุณกำลังส่งข้อมูลโพสต์
  3. คลิกที่มัน
  4. ในส่วนหัวคุณสามารถเลือกขอ Payload เพื่อตรวจสอบข้อมูลโพสต์

DevTools ของ Chrome



5

ข้อมูลแบบฟอร์มไม่ปรากฏในคอนโซลของเว็บเบราว์เซอร์

for (var data of formData) {
  console.log(data);
}

ลองวิธีนี้จะแสดง


2

ในกรณีของฉันบนเบราว์เซอร์ Edge:

  const formData = new FormData(this.form);
  for (const [key, value] of formData.entries()) {
      formObject[key] = value;
  }

ให้ข้อผิดพลาดเดียวกันกับฉัน

ดังนั้นฉันไม่ได้ใช้FormDataและฉันแค่สร้างวัตถุด้วยตนเอง

import React from 'react';    
import formDataToObject from 'form-data-to-object';

  ...

let formObject = {};

// EDGE compatibility -  replace FormData by
for (let i = 0; i < this.form.length; i++) {
  if (this.form[i].name) {
    formObject[this.form[i].name] = this.form[i].value;
  }
}

const data = formDataToObject.toObj(formObject): // convert "user[email]":"customer@mail.com" => "user":{"email":"customer@mail.com"}

const orderRes = await fetch(`/api/orders`, {
        method: 'POST',
        credentials: 'same-origin',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify(data)
      });

const order = await orderRes.json();

2

เวอร์ชันตอบสนอง

ตรวจสอบให้แน่ใจว่ามีส่วนหัวด้วย 'content-type': 'multipart/form-data'

_handleSubmit(e) {
    e.preventDefault();
    const formData = new FormData();
          formData.append('file', this.state.file);
    const config = {
      headers: {
        'content-type': 'multipart/form-data'
      }
    }

     axios.post("/upload", formData, config)
         .then((resp) => {
             console.log(resp)
         }).catch((error) => {
    })
  }

  _handleImageChange(e) {
    e.preventDefault();
    let file = e.target.files[0];
    this.setState({
      file: file
    });
  }

ดู

  #html
 <input className="form-control"
    type="file" 
    onChange={(e)=>this._handleImageChange(e)} 
 />
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.