web-dev-qa-db-fra.com

fetch - Limite manquante dans multipart/form-data POST

merci d'être passé.

Je souhaite envoyer un new FormData() en tant que body d'une demande POST à l'aide de fetch api

l'opération ressemble à quelque chose comme ça

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

le problème est que la limite, quelque chose comme 

boundary=----WebKitFormBoundaryyEmKNDsBKjB7QEqu

ne le fait jamais dans l'en-tête Content-Type:

ça devrait ressembler à ça

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

lorsque vous essayez la "même" opération avec new XMLHttpRequest(), comme si

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

les en-têtes sont correctement définis

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

donc ma question est, 

  1. comment faire pour que fetch se comporte exactement comme XMLHttpRequest dans cette situation?

  2. si ce n'est pas possible, pourquoi?

Merci à tous! Cette communauté est plus ou moins la raison pour laquelle j'ai du succès professionnel.

25
James

La solution au problème consiste à définir explicitement Content-Type sur undefined afin que votre navigateur ou le client que vous utilisez puisse le définir et y ajouter cette valeur de limite. Décevant mais vrai. 

59
James
fetch(url,options)
  1. Si vous définissez une chaîne sur options.body, vous devez définir le Content-Type dans l'en-tête de la requête, sinon ce sera text/plain par défaut.
  2. Si options.body est un objet spécifique tel que let a = new FormData() ou let b = new URLSearchParams(), vous n'avez pas à définir le Content-Type à la main. Il sera ajouté automatiquement. 

    • pour a, ce sera quelque chose comme

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

    comme vous le voyez, la limite est automatiquement ajoutée.

    • pour b, il s'agit de application/x-www-form-urlencoded;
6
moonreader

J'utilise le aurelia-api (un wrapper à aurelia-fetch-client). Dans ce cas, le type de contenu par défaut est 'application/json'. Donc, je ai défini le type de contenu sur non défini et cela a fonctionné comme un charme.

2
Diego Troitiño

J'ai supprimé "Content-Type" et ajouté "Accept" aux en-têtes http et cela a fonctionné pour moi. Voici les en-têtes que j'ai utilisés,

'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
ravichandra vydhya

Ajouter le navigateur headers:{content-type: undefined} générera une limite pour vous Il s’agit de télécharger un fichier avec diffusion en continu Si vous ajoutez des données multiples/de formulaire, cela signifie que vous devez créer une diffusion en continu et télécharger votre partie de fichier et partie

Donc, il est correct d'ajouter request.headers = {content-type: undefined}

0
Nver Abgaryan