FormData.append („klucz”, „wartość”) nie działa


107

Czy możesz mi powiedzieć, co jest w tym złego:

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

Mój wynik wygląda tak, nie mogę znaleźć mojej pary „klucz” - „wartość”

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

Nie rozumiem! Wczoraj działało tak dobrze, a dzisiaj moja głowa tyle razy rozwaliła klawiaturę! Firefox, Chrome, oba takie same: /

Odpowiedzi:


127

Nowości w Chrome 50+ i Firefox 39+ (odp. 44+):

  • formdata.entries()(w połączeniu z w Array.from()celu debugowania)
  • formdata.get(key)
  • i bardziej przydatne metody

Oryginalna odpowiedź:

Zwykle robię „debugowanie” FormDataobiektu, po prostu wysyłam go (gdziekolwiek!) I sprawdzam dzienniki przeglądarki (np. Zakładka Sieć Chrome devtools).

Nie potrzebujesz tego samego frameworka Ajax. Nie potrzebujesz żadnych szczegółów. Po prostu wyślij:

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

Łatwo.


dzięki - był to przydatny szybki sposób na pobranie obiektu FormData przez wpisanie go w konsoli Chrome.
Dan Smart

Według Google metody formData zostały dodane w Chrome v50.
thdoan

Jak byś spojrzał na dzienniki przeglądarki, jeśli jest to przeglądarka mobilna, taka jak Safari? Używam obiektu FormData w aplikacji internetowej przeznaczonej na urządzenia mobilne i nie mogę dowiedzieć się, jak go debugować.
kiwicomb123

1
@ kiwicomb123 Formdata.entries()+ Array.from()+, alert()jeśli jest wystarczająco nowoczesny, lub spójrz na debugowanie urządzeń mobilnych
Rudie

więc nie ma krawędzi lub IE11?
SuperUberDuper

50

Mówisz, że to nie działa. Czego się spodziewasz?

Nie ma sposobu na wydobycie danych z FormDataobiektu; jest przeznaczony tylko do wysyłania danych wraz z XMLHttpRequestobiektem (dla sendmetody).

Zaktualizuj prawie pięć lat później: w niektórych nowszych przeglądarkach nie jest to już prawdą i możesz teraz zobaczyć dostarczone dane, FormDataoprócz tylko upychania danych. Aby uzyskać więcej informacji, zobacz zaakceptowaną odpowiedź .


20
OK ... to jest do bani. Dlaczego nie mogę zalogować danych FormData w mojej konsoli? :-( To po prostu nie ma dla mnie sensu, ponieważ myślałem, że to zwykły obiekt
netzaffin

12
@netzaffin: Zarówno Firebug, jak i inspektor Chrome pozwalają zobaczyć parametry wysłanego żądania w żądaniu XHR, o ile otworzyłeś kartę sieci i zacząłeś rejestrować, więc powinieneś sobie z tym poradzić. Można również utworzyć obiekt opakowujący, który rejestruje pola i dołącza je do FormData, a następnie sprawdza, czy są to wartości (nie zapominając o wysłaniu wewnętrznego FormData zamiast obiektu opakowania).
Jesper

1
Czy przynajmniej mogę sprawdzić, czy formdataobiekt zawiera plik?
MarceloBarbosa

1
@MarceloBarbosa: Wygląda na to, że nie można wyciągnąć z tego żadnych informacji. Musisz tylko zachować te informacje.
Jesper

Jak zauważył @Jesper, możesz sprawdzić żądanie XHR wysłane na karcie sieciowej narzędzi programistycznych, jest tam opcja Params, która pozwala nawet zobaczyć zawartość wysłanego żądania POST. Również odpowiedź.
Anirudh

23

Mogłeś mieć ten sam problem, co ja na początku. Próbowałem użyć FormData, aby pobrać wszystkie moje pliki wejściowe w celu przesłania obrazu, ale jednocześnie chciałem dołączyć identyfikator sesji do informacji przekazywanych na serwer. Przez cały ten czas myślałem, że dołączając informacje, będzie można je zobaczyć na serwerze, uzyskując dostęp do obiektu. Myliłem się. Po dołączeniu do FormData sposobem sprawdzenia dołączonych informacji na serwerze jest proste $_POST['*your appended data*']zapytanie. tak jak:

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

następnie na php:

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

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

17

Jeśli jesteś w Chrome, możesz sprawdzić dane posta

Oto jak sprawdzić dane posta

  1. Przejdź do zakładki Sieć
  2. Poszukaj łącza, do którego wysyłasz dane posta
  3. Kliknij na to
  4. W nagłówkach możesz zaznaczyć Request Payload, aby sprawdzić dane wiadomości

Chrome's DevTools



5

dane formularzy nie pojawiają się w konsoli przeglądarki internetowej

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

spróbuj w ten sposób to pokaże


2

W moim przypadku w przeglądarce Edge:

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

podaj mi ten sam błąd

Więc nie używam FormDatai po prostu ręcznie buduję obiekt

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

React Version

Upewnij się, że masz nagłówek z '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
    });
  }

Widok

  #html
 <input className="form-control"
    type="file" 
    onChange={(e)=>this._handleImageChange(e)} 
 />
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.