web-dev-qa-db-de.com

fetch - Fehlende Grenze in Multipart-/Formulardaten POST

danke für's vorbeikommen.

Ich möchte eine new FormData() als body einer POST-Anfrage mit der fetch-API senden.

die Operation sieht ungefähr so ​​aus

var formData = new FormData()
formData.append('myfile', file, 'someFileName.csv')

fetch('https://api.myapp.com', 
  {
    method: 'POST',
    headers: {
      "Content-Type": "multipart/form-data"
    },
    body: formData
  }
)

das problem hier ist, dass die grenze so etwas ähnelt 

boundary=----WebKitFormBoundaryyEmKNDsBKjB7QEqu

schafft es niemals in den Content-Type:-Header

es sollte so aussehen

Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryyEmKNDsBKjB7QEqu

wenn Sie die gleiche Operation mit einer new XMLHttpRequest() ausführen, wie es so ist

var request = new XMLHttpRequest()
request.open("POST", "https://api.mything.com")
request.withCredentials = true
request.send(formData)

die Header sind richtig eingestellt

Content-Type:multipart/form-data; boundary=----WebKitFormBoundaryyEmKNDsBKjB7QEqu

also meine frage ist, 

  1. wie mache ich, dass sich fetch in dieser Situation genau wie XMLHttpRequest verhält?

  2. wenn dies nicht möglich ist, warum?

Danke an alle! Diese Gemeinschaft ist mehr oder weniger der Grund, warum ich beruflichen Erfolg habe.

25
James

Die Lösung des Problems besteht darin, Content-Type explizit auf undefined zu setzen, damit Ihr Browser oder der von Ihnen verwendete Client ihn festlegen und diesen Grenzwert für Sie hinzufügen kann. Enttäuschend aber wahr. 

59
James
fetch(url,options)
  1. Wenn Sie eine Zeichenfolge als options.body festlegen, müssen Sie Content-Type im Anforderungsheader festlegen. Andernfalls ist dies text/plain.
  2. Wenn options.body ein bestimmtes Objekt wie let a = new FormData() oder let b = new URLSearchParams() ist, müssen Sie den Content-Type nicht manuell festlegen. Er wird automatisch hinzugefügt. 

    • für a wird es ungefähr so ​​sein

    multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW

    wie Sie sehen, wird die Grenze automatisch hinzugefügt.

    • für b ist es application/x-www-form-urlencoded;
6
moonreader

Ich hatte das gleiche Problem und konnte es beheben, indem ich die Eigenschaft Content-Type Ausschloss, sodass der Browser den Rahmen und den Inhaltstyp automatisch erkennen und festlegen konnte.

Ihr Code wird:

var formData = new FormData()
formData.append('myfile', file, 'someFileName.csv')

fetch('https://api.myapp.com',
  {
    method: 'POST',
    body: formData
  }
)
3
Andrew Faulkner

Ich verwende die aurelia-api (ein Wrapper für Aurelia-Fetch-Client). In diesem Fall lautet der Standardwert für "Content-Type" "application/json". Also habe ich den Content-Type auf undefined gesetzt und es funktionierte wie ein Zauber.

2
Diego Troitiño

Ich entfernte "Content-Type" und fügte "Accept" zu den http-Headern hinzu. Hier sind die Header, die ich verwendet habe,

'headers': new HttpHeaders({
        // 'Content-Type': undefined,
        'Accept': '*/*',
        'Authorization': 
        "Bearer "+(JSON.parse(sessionStorage.getItem('token')).token),
        'Access-Control-Allow-Origin': this.apiURL,
        'Access-Control-Allow-Methods': 'GET, POST, OPTIONS, PUT, PATCH, DELETE',
        'Access-Control-Allow-Headers': 'Origin,X-Requested-With,content-type,accept',
        'Access-Control-Allow-Credentials': 'true' 

      })
1

Durch Hinzufügen von headers:{content-type: undefined} browser wird eine Begrenzung für Sie erstellt Für das Hochladen einer Datei mit Teil und Teil mit Streaming Wenn Sie 'multiple/form-data' hinzufügen, müssen Sie das Streaming erstellen und Ihren Dateiabschnitt hochladen -und-teil

Es ist also in Ordnung, request.headers = {content-type: undefined} hinzuzufügen.

0
Nver Abgaryan