Abrufen gibt einen leeren Antworttext


73

Ich habe eine React / Redux-Anwendung und versuche, eine einfache GET-Anfrage an einen Server zu senden:

fetch('http://example.com/api/node', {
  mode: "no-cors",
  method: "GET",
  headers: {
    "Accept": "application/json"
  }
}).then((response) => {
  console.log(response.body); // null
  return dispatch({
    type: "GET_CALL",
    response: response
  });
})
.catch(error => { console.log('request failed', error); });

Das Problem ist, dass der Antworttext in der .then()Funktion leer ist und ich nicht sicher bin, warum. Ich habe Beispiele online überprüft und es sieht so aus, als ob mein Code funktionieren sollte, sodass mir hier offensichtlich etwas fehlt. Die Sache ist, wenn ich die Registerkarte "Netzwerk" in den Entwicklertools von Chrome überprüfe, wird die Anfrage gestellt und ich erhalte die Daten, nach denen ich suche.

Kann jemand ein Licht auf dieses werfen?

BEARBEITEN:

Ich habe versucht, die Antwort zu konvertieren.

mit .text():

fetch('http://example.com/api/node', {
  mode: "no-cors",
  method: "GET",
  headers: {
    "Accept": "application/json"
  }
})
.then(response => response.text())
.then((response) => {
  console.log(response); // returns empty string
  return dispatch({
    type: "GET_CALL",
    response: response
  });
})
.catch(error => { console.log('request failed', error); });

und mit .json():

fetch('http://example.com/api/node', {
  mode: "no-cors",
  method: "GET",
  headers: {
    "Accept": "application/json"
  }
})
.then(response => response.json())
.then((response) => {
  console.log(response.body);
  return dispatch({
    type: "GET_CALL",
    response: response.body
  });
})
.catch(error => { console.log('request failed', error); }); // Syntax error: unexpected end of input

In den Chrome Dev Tools suchen:

Geben Sie hier die Bildbeschreibung ein


Ich konnte mich nicht fetchan die Arbeit machen und begann mit der Redux-API-Middleware . Wenn Sie die Anfrage stellen, müssen Sie die Antwort auf ähnliche Weise in json konvertieren, wie die Leute hier vorgeschlagen haben:
Razvan Ilin

Antworten:


159

Ich bin gerade darauf gestoßen. Wie in dieser Antwort erwähnt , erhalten Sie mit using mode: "no-cors"eine opaque response, die anscheinend keine Daten im Körper zurückgibt.

undurchsichtig: Antwort auf "No-Cors" -Anforderung an eine Cross-Origin-Ressource. Stark eingeschränkt .

In meinem Fall habe ich verwendet Express. Nachdem ich cors for Express installiert und konfiguriert und entfernt hatte mode: "no-cors", wurde mir ein Versprechen zurückgegeben. Die Antwortdaten werden im Versprechen sein, z

fetch('http://example.com/api/node', {
  // mode: 'no-cors',
  method: 'GET',
  headers: {
    Accept: 'application/json',
  },
},
).then(response => {
  if (response.ok) {
    response.json().then(json => {
      console.log(json);
    });
  }
});

3
Für mich war alles, was erforderlich war, .then(json => {das Ende meiner response.json()Aussage hinzuzufügen . Vielen Dank!
Mike Kellogg

2
@MikeKellogg ist nur ein Hinweis darauf, dass Sie return response.json()den .then(json=>Teil zwischen der letzten Klammer und dem Semikolon platzieren können, falls Sie Ihren Code aufgeräumt halten möchten . ).then(json=>{});
Razvan Ilin

Es scheint, wenn Sie die Domain verlassen und eine relative URI verwenden, mit der sie funktioniertno-cors
Danny '365CSI' Engelman

29

Sie müssen Ihre responsein konvertieren , jsonbevor Sie darauf zugreifen könnenresponse.body

Aus den Dokumenten

fetch(url)
  .then(response => response.json())
  .then(json => {
    console.log('parsed json', json) // access json.body here
  })

6

Sie müssen den Text der Antwort lesen:

fetch(url)
  .then(res => res.text()) // Read the body as a string

fetch(url)
  .then(res => res.json()) // Read the body as JSON payload

Sobald Sie den Körper gelesen haben, können Sie ihn manipulieren:

fetch('http://example.com/api/node', {
  mode: "no-cors",
  method: "GET",
  headers: {
    "Accept": "application/json"
  }
})
  .then(response => response.json())
  .then(response => {
    return dispatch({
      type: "GET_CALL",
      response: response
    });
  })

Danke für die Antwort! Ich habe das versucht, aber ich kann immer noch die richtige Antwort bekommen. Überprüfen Sie die bearbeitete Frage.
Razvan Ilin

@ RasvanIlin Verwenden Sie .json()anstelle von.text()
Florent

1
Entschuldigung, ich habe gerade festgestellt, dass ich im letzten Beispiel das falsche Snippet kopiert habe. Ich habe es tatsächlich verwendet json(), aber ich erhalte den Syntaxfehler, der vermutlich ausgelöst wird, weil er die Antwort nicht in json konvertieren kann
Razvan Ilin

Versuchte dies und es funktionierte für mich. response.json()tat die Magie. Sobald ich es hatte, konnte ich console.log und meine Antwort erhalten. Danke
Hanmaslah

3
Ich versuche immer noch, meinen Kopf um diesen no-corsModus zu wickeln . Ich bin in einer ähnlichen Situation. Bei Verwendung von Variationen der Lösungen hier scheint der No-Cors-Abruf erfolgreich zu sein ... kein x-origin-Fehler, und in meinem Netzwerkinspektor kann ich Daten in Vorschau und Antwort SEHEN. Aber ich kann einfach nicht auf die Daten des Antwortobjekts zugreifen, das an mein übergeben wurde then. json() text()keiner scheint viel zu tun. Bedeutet eine undurchsichtige Antwort, dass die Daten nullabgerufen werden und nach Abschluss nicht mehr darauf zugegriffen werden kann? : - /
jmk2142

4
fetch("http://localhost:8988/api", {
        //mode: "no-cors",
        method: "GET",
        headers: {
            "Accept": "application/json"
        }
    })
    .then(response => {
        return response.json();
    })
    .then(data => {
        return data;
    })
    .catch(error => {
        return error;
    });

Das funktioniert bei mir.


3
fetch("http://localhost:8988/api", {
    method: "GET",
    headers: {
       "Content-Type": "application/json"
    }
})
.then((response) =>response.json());
.then((data) => {
    console.log(data);
})
.catch(error => {
    return error;
});

2
Während dieser Code die Frage des OP beantworten kann, würden ein paar erklärende Worte einen großen Beitrag dazu leisten, dass aktuelle und zukünftige Leser Ihre Antwort verstehen.
Thom

Dies ist tatsächlich ein sehr ähnliches Beispiel wie andere Antworten hier. Ich bin mir nicht sicher über die Richtlinien von SO, aber ich bin mir nicht sicher, ob dies erlaubt ist
Razvan Ilin

Nur ist es nicht dasselbe. "Content-Type" ist einzigartig. Schade, dass es bei mir nicht funktioniert hat :(
Michael

2

Versuchen Sie, response.json () zu verwenden :

fetch('http://example.com/api/node', {
  mode: "no-cors",
  method: "GET",
  headers: {
    "Accept": "application/json"
  }
}).then((response) => {
  console.log(response.json()); // null
  return dispatch({
    type: "GET_CALL",
    response: response.json()
  });
})
.catch(error => { console.log('request failed', error); });

1

Dies erfordert Änderungen am Frontend-JS und den vom Backend gesendeten Headern.

Vorderes Ende

Entfernen Sie "mode":"no-cors"in den Abrufoptionen.

fetch(
  "http://example.com/api/docs", 
  {
    // mode: "no-cors",
    method: "GET"
  }
)
  .then(response => response.text())
  .then(data => console.log(data))

Backend

Wenn Ihr Server auf die Anfrage antwortet, fügen Sie die CORS-Header hinzu, die den Ursprung angeben, von dem die Anfrage kommt. Wenn Sie sich nicht für den Ursprung interessieren, geben Sie den *Platzhalter an.

Die Rohantwort sollte einen solchen Header enthalten.

Access-Control-Allow-Origin: *

0

In vielen Fällen müssen Sie das bodyParser-Modul in Ihrer Express Node-App hinzufügen. Fügen Sie dann in Ihrem App.use-Teil unten app.use(express.static('www')); diese 2 Zeilen hinzu app.use(bodyParser.urlencoded({ extended: true })); app.use(bodyParser.json());

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.