25

I'm trying to make a request in a local file, but I don't know when I try to do on my computer show me an error. Is possible make a fetch to a file inside your project?

 // Option 1
 componentDidMount() {
     fetch('./movies.json')
     .then(res => res.json())
     .then((data) => {
        console.log(data)
     });
 }

 error: Uncaught (in promise) SyntaxError: Unexpected token < in JSON at position 0 at App.js: 10 -->  .then(res => res.json())

 // Option 2
 componentDidMount() {
    fetch('./movies.json', {
       headers : { 
         'Content-Type': 'application/json',
         'Accept': 'application/json'
       }
    })
   .then( res => res.json())
   .then((data) => {
        console.log(data);
   });
 }

 error1: GET http://localhost:3000/movies.json 404 (Not Found) at App.js:15 --> fetch('./movies.json', {
 error2: Uncaught (in promise) SyntaxError: Unexpected token < in JSON at position 0 at App.js: 10 -->  .then(res => res.json())


 // This works
 componentDidMount() {
   fetch('https://facebook.github.io/react-native/movies.json')
   .then( res => res.json() )
   .then( (data) => {
      console.log(data)
   })
 }
patelarpan
  • 4,756
  • 15
  • 21
Javier
  • 1,409
  • 1
  • 14
  • 30
  • 3
    You're not going to be able to fetch it like that because your local server doesn't know what `movies.json` is. I would suggest either using `import`, or adding a route to serve the file in your api – Brandon Mowat Apr 24 '18 at 16:52
  • 1
    It appears as though that file does not exist, from the second error `GET http://localhost:3000/movies.json 404 (Not Found)`. We can't tell you where your file is... – Heretic Monkey Apr 24 '18 at 17:18

10 Answers10

23

You are trying to serve a static file with a fetch command, which inherently requires the file to be served by a server. To resolve the issue, you have a few options available to you. I am going to outline the two that are most commonly suggested for such a thing:

  • Use Node.js and something like expressjs to host your own server that serves the file you want to fetch. While this procedure might require more effort and time, it is certainly more customizable and a good way to learn and understand how fetching from a backend works.
  • Use something like Chrome Web Server to easily set up a very simple server to serve your file on your local network. Using this method, you have very little control over what you can do with said web server, but you can quickly and easily prototype your web application. However, I doubt there's a way to move this method to production.

Finally, there are other options where you can upload one or more files online and fetch them from an external URL, however this might not be the optimal strategy.

Angelos Chalaris
  • 5,882
  • 7
  • 44
  • 65
16

Try to place your json file in the public folder like so :

public/movies.json

and then fetch using

fetch('./movies.json')

or

fetch('movies.json')

I have experienced the same problem previously. When I place the json file in the public folder, problem is solved. When using fetch, React normally reads asset/resources files in the public folder.

Lex Soft
  • 1,173
  • 9
  • 10
14

Your JSON file needs to be served by the server so you need the express server (or any other). In this example we are using using express.

Note: you can also download git repo

App.js File

import React, { Component } from 'react';

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      data: null
    };
  }

  componentDidMount() {
    const myHeaders = new Headers({
      "Content-Type": "application/json",
      Accept: "application/json"
    });

    fetch("http://localhost:5000/movie", {
      headers: myHeaders,

    })
      .then(response => {
        console.log(response);
        return response.json();
      })
      .then(data => {
        console.log(data);
        this.setState({ data });
      });
  }

  render() {
    return <div className="App">{JSON.stringify(this.state.data)}</div>;
  }
}

export default App;

server.js

var express = require("express");
var data = require('./movie.json'); // your json file path
var app = express();


app.use(function(req, res, next) {
  res.header("Access-Control-Allow-Origin", "*");
  res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
  next();
});

app.get("/movie", function(req, res, next) {
  res.send(data);
});

app.listen(5000, () => console.log('Example app listening on port 5000!'))
patelarpan
  • 4,756
  • 15
  • 21
6

I was encountering the same error and there are two changes I made in my code to get rid of the error. Firstly, you don't need an express server to serve your files you can read data from a local json file inside your public folder in your create-react-app directory.

  const getData=()=>{
     fetch('data.json',{
          headers : { 
            'Content-Type': 'application/json',
            'Accept': 'application/json'
           }
         }
        )
         .then(function(response){
            console.log(response)
            return response.json();
          })
           .then(function(myJson) {
              console.log(myJson);
            });
      }
      useEffect(()=>{
        getData()
      },[])

First, as suggested in some of the answers above ensure that your json file is inside the public folder and the path parameter inside the fetch function is correct as above. Relative paths didn't work for me. Second, set the headers as shown. Removing the headers part from my fetch call was still giving me this error.

Siddhant Varma
  • 388
  • 2
  • 8
2

a simple solution to this is to use live server extension (if you use vs code)

1

My go-to approach is to use express-generator to set up a quick local server, then run ngrok (free tier is fine) and point your app to the url it creates. This has the advantage of letting you easily test your fetching in the iOS simulator or Android emulator, as well as on a device not tethered to your computer. Plus, you can also send the url to people testing your app. Of course, there would need to be a way for them to manually input that url so the app could set it as the fetch endpoint.

vm909
  • 481
  • 3
  • 7
1

Say that i have the following file test.html

 <html>
   <head>
 <meta charset="UTF-8" />
 </head>
 <body>
 <script> 
 var depdata;
 depdata =  fetch("test1.geojson")
.then((data) => {
    return data;
});

 depdata.then(function(data) {console.log(data)})
   </script>
 </body>
 </html>

When access the file in the firefox through file://... I get the following error:

  Cross-Origin Request Blocked:....

When I followed the error on firefox I got the following explanation

CORS requests may only use the HTTPS URL scheme, but the URL specified by the request is of a different type. This often occurs if the URL specifies a local file, using a file:/// URL.

To fix this problem, simply make sure you use HTTPS URLs when issuing requests involving CORS, such as XMLHttpRequest, Fetch APIs, Web Fonts (@font-face), and WebGL textures, and XSL stylesheets.

So the as far as I understand we just need to access the test.html through HTTP. The most straight forward way around this problem was the python simple http server. In the terminal.

> cd directory of the project.
> python3 -m http.server 8000 --bind 127.0.0.1 

Then in the browser:

http://localhost:8000/test.html
Community
  • 1
  • 1
DJJ
  • 2,281
  • 2
  • 24
  • 50
0

You can place your json file in the public folder. In your React component you can use userEffect (). You don't need Express.js for this case.

React.useEffect(() => { 
   fetch("./views/util/cities.json")
      .then(function(response) {
        return response.json();
      })
      .then(function(myJson) {
        console.log(myJson);
      });
  });
lazos
  • 898
  • 1
  • 5
  • 17
0

I got it working rather very simple way - no express / webserver really needed. Just do :

import data from '../assets/data.json';

and use the json data like this (say if it is a JsonArray) : data.map(movie ...

Do this in App.js or some other class extending React.Component,

khanna
  • 555
  • 8
  • 20
0

The error

Unexpected token < in JSON at position 0

comes from the HTML file that is returned if the request is unsuccessful. The first element (at position 0) of an HTML file is typically a '<'. Instead of a JSON, an attempt is made to read in an HTML file.

You can find the returned HTML File in the Inspect Tool -> Network -> Erroneous file marked in red -> Reponse. There you can see what the specific error is. Example Error Message

To fix the error for me, it helped to move the file to be imported to the Public folder of my React project and then import it like this from a file in the 'src' folder: fetch('dataTemplate.json')

Alex F.
  • 16
  • 2