简体   繁体   中英

Get a JSON response from ESP8266 using fetch

I've created a ESP8266 web server that should send a JSON object when it's requested by the client. The code of this server looks like this:

#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include <ESP8266WiFi.h>

void setup() {
  Serial.begin(115200);
  WiFi.disconnect();
  delay(10);
  Serial.print("Connecting to ");
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Successfully connected.");
  Serial.println("\nGot IP: ");  
  Serial.print(WiFi.localIP());
  if(MDNS.begin("esp8266")) {
    Serial.println("MDNS responder started");
  }
  server.on("/data", []() {
    server.send(200, "application/json", "{\"key\": \"value\"}");
  });
  server.begin();
  Serial.println("HTTP server started");
}

void loop() { 
  server.handleClient();
  MDNS.update();
}

Then I am trying to request the data from my JS code using fetch function. But it throws this error:

Uncaught (in promise) SyntaxError: Unexpected end of input
    at index.js:8

When I simply connect to the server's data from my browser it is correctly displayed the JSON object on the page. This is my code to do request:

fetch('http://192.168.1.135/data', {
  method: 'GET',
  mode: 'no-cors',
  headers: {
    'Content-Type': 'application/json',
  }
})
  .then(response => response.json())
  .then(data => console.log(data));

tl;dr

Remove mode: 'no-cors' and add server.sendHeader("Access-Control-Allow-Origin", "*") in the sketch.

Fetch modes

mode: 'no-cors' is intended for caching with Service Workers.

JavaScript may not access any properties of the resulting Response

source: https://developer.mozilla.org/en-US/docs/Web/API/Request/mode

Hence, you are telling the engine to convert "nothing" to JSON which in turn leads to "Unexpected end of input".

Alternative explanation: https://stackoverflow.com/a/36303436/131929

Use this trimmed JavaScript snippet; it's straight from the book.

fetch('http://esp8266.local/data')
  .then(response => response.json())
  .then(data => console.log(data));

To use this even across the same-origin constraints , which apply unless the snippet is embedded in a (HTML) resource served by esp8266.local, the server needs to send a CORS header.

server.on("/data", []() {
  Serial.println("Serving /data");
  server.sendHeader("Access-Control-Allow-Origin", "*");
  server.send(200, "application/json", "{\"key\": \"value\"}");
});

Goodie

headers: {'Content-Type': 'application/json'} is pointless because Content-Type is a response header . If at all you will want to use the 'Accept' request header .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM