web-dev-qa-db-fra.com

Comment télécharger un fichier avec l'API JS Fetch?

J'essaie encore de m'envelopper la tête.

Je peux demander à l'utilisateur de sélectionner le fichier (ou même plusieurs) avec l'entrée de fichier:

<form>
  <div>
    <label>Select file to upload</label>
    <input type="file">
  </div>
  <button type="submit">Convert</button>
</form>

Et je peux attraper l'événement submit en utilisant <fill in your event handler here>. Mais une fois que je le fais, comment puis-je envoyer le fichier en utilisant fetch?

fetch('/files', {
  method: 'post',
  // what goes here? What is the "body" for this? content-type header?
}).then(/* whatever */);
133
deitch

Ceci est un exemple de base avec des commentaires. La fonction upload est ce que vous recherchez:

// Select your input type file and store it in a variable
const input = document.getElementById('fileinput');

// This will upload the file after having read it
const upload = (file) => {
  fetch('http://www.example.net', { // Your POST endpoint
    method: 'POST',
    headers: {
      // Content-Type may need to be completely **omitted**
      // or you may need something
      "Content-Type": "You will perhaps need to define a content-type here"
    },
    body: file // This is your file object
  }).then(
    response => response.json() // if the response is a JSON object
  ).then(
    success => console.log(success) // Handle the success response object
  ).catch(
    error => console.log(error) // Handle the error response object
  );
};

// Event handler executed when a file is selected
const onSelectFile = () => upload(input.files[0]);

// Add a listener on your input
// It will be triggered when a file will be selected
input.addEventListener('change', onSelectFile, false);
98
Damien

Je l'ai fait comme ça:

var input = document.querySelector('input[type="file"]')

var data = new FormData()
data.append('file', input.files[0])
data.append('user', 'hubot')

fetch('/avatars', {
  method: 'POST',
  body: data
})
179
Integ

Une note importante pour l'envoi de fichiers avec l'API Fetch

Il faut omettre l'en-tête content-type pour la demande d'extraction. Ensuite, le navigateur ajoutera automatiquement l'en-tête Content type, y compris la limite de formulaire, qui ressemble à

Content-Type: multipart/form-data; boundary=—-WebKitFormBoundaryfgtsKTYLsT7PNUVD

La limite de formulaire est le délimiteur pour les données de formulaire

59
madhu131313

Si vous voulez multiples fichier, vous pouvez utiliser ceci

var input = document.querySelector('input[type="file"]')

var data = new FormData()
for (const file of input.files) {
  data.append('files',file,file.name)
}

fetch('/avatars', {
  method: 'POST',
  body: data
})
25
Alex Montoya

Pour soumettre un seul fichier, vous pouvez simplement utiliser l'objet File du tableau .files du input directement comme valeur de body: dans votre initialiseur fetch() :

const myInput = document.getElementById('my-input');

// Later, perhaps in a form 'submit' handler or the input's 'change' handler:
fetch('https://example.com/some_endpoint', {
  method: 'POST',
  body: myInput.files[0],
});

Cela fonctionne parce que File hérite de Blob , et Blob est l’une des valeurs permises BodyInit types définis dans la norme d'extraction.

16
Mark Amery

Sautant de l'approche d'Alex Montoya pour plusieurs éléments de saisie de fichier

const inputFiles = document.querySelectorAll('input[type="file"]');
const formData = new FormData();

for (const file of inputFiles) {
    formData.append(file.name, file.files[0]);
}

fetch(url, {
    method: 'POST',
    body: formData })
2
Jerald Macachor

Le problème pour moi était que j'utilisais un response.blob () pour remplir les données du formulaire. Apparemment, vous ne pouvez pas le faire au moins avec réagir natif, donc je me suis retrouvé à utiliser

data.append('fileData', {
  uri : pickerResponse.uri,
  type: pickerResponse.type,
  name: pickerResponse.fileName
 });

Fetch semble reconnaître ce format et envoyer le fichier vers lequel l'URI pointe.

1
NickJ