Je poste une demande sur mon serveur d'arrière-plan en utilisant fetch api dans React js

const formData = new FormData();
    formData.append("image", file);
    formData.append("userId", currentUser.id);
    formData.append("sliderNumber", sliderNumber);

    const myHeaders = new Headers();
    myHeaders.append("Content-Type", file.type);
    myHeaders.append("Aceess-Control-Allow-Origin", "*");

    fetch("http://localhost:4000/upload/slide-image", {
      method: "POST",
      headers: myHeaders,
      mode: "no-cors",
      body: formData
    })
      .then(response => response)
      .then(data => console.log("Printing data: ", data));
  };

Dans le backend d'élixir

def upload(conn, params) do
  # uploading code 

  #send response to the client with amazon s3 image url
  send_resp(conn, 200, image_url)
end

Mais l'objet de réponse de la récupération de l'API est vide

Response {
  body: null
  bodyUsed: false
  headers: Headers {}
  ok: false
  redirected: false
  status: 0
  statusText: ""
  type: "opaque"
  url: ""
}

Et cela ne change pas lorsque je réponds avec le code d'état 400.

Il semble que fetch api ne construise pas correctement l'objet Reponse à un moment donné. Parce que je peux trouver le code d'état et le corps de réponse corrects dans l'onglet réseau du navigateur. Mais l'objet Response ne contient pas de réponse du serveur principal.

Une idée?

0
freewebwithme 25 avril 2020 à 00:25

3 réponses

Meilleure réponse

Si vous attendez une réponse textuelle de votre serveur, alors sur votre premier .then(.., vous devriez faire comme:

fetch("http://localhost:4000/upload/slide-image", {
      method: "POST",
      headers: myHeaders,
      mode: "no-cors",
      body: formData
    })
      .then(response => response.text()) // <--- 
      .then(data => console.log("Printing data: ", data));

fetch renvoie une promesse qui se résout en une réponse . Lorsque vous utilisez .text() à ce stade, ce que vous faites réellement est de prendre le flux de réponse, de le lire jusqu'à la fin et de renvoyer une promesse qui se résoudra avec un texte.

En dehors de cela, vous utilisez également mode: "no-cors" (comme d'autres utilisateurs l'ont mentionné dans leurs réponses) qui vous limite de plusieurs façons. Par exemple, même si vous suivez mes instructions ci-dessus, vous obtiendrez une chaîne vide, même si vous essayez de renvoyer quelque chose depuis votre serveur. Et ce sera à cause de ce mode.

Vous pouvez trouver plus de détails à ce sujet ici, sous puce no-cors .

2
Michalis Garganourakis 24 avril 2020 à 21:57
 mode: "no-cors",

Vous définissez le mode sur no-cors, donc la réponse est Opaque, ce qui signifie que vous ne pouvez pas voir à l'intérieur.

Ne faites pas cela si vous avez besoin de lire la réponse.


A part:

myHeaders.append("Content-Type", file.type);

C'est le mauvais type de contenu pour un objet de données de formulaire. Ne définissez pas le type de contenu. L'API de récupération définira automatiquement la bonne.

   myHeaders.append("Aceess-Control-Allow-Origin", "*");

Access-Control-Allow-Origin, que vous avez mal orthographié, est un en-tête de réponse , pas un en-tête de demande.

.then(response => response)

Renvoyer la réponse inchangée est plutôt inutile. Vous voudrez probablement response.text() si vous récupérez une URL simple.

1
Quentin 24 avril 2020 à 21:36

Votre Content-Type est faux. Lors de l'envoi de fichiers avec d'autres données, le Content-Type doit toujours être multipart/form-data.

3
Robo Robok 24 avril 2020 à 21:28