53

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
  • 7,188
  • 2
  • 20
  • 25
Javier
  • 1,975
  • 3
  • 24
  • 46
  • 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
  • How would you do this when running your application on any server? Should it always access the user's file system? – Nico Haase Jun 13 '23 at 08:56

12 Answers12

33

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
  • 2,308
  • 2
  • 13
  • 13
  • 1
    This worked for me. I first put /public in /src/ but this failed, it has to be in the root dir, same place as your package.json etc. It also has to be named "public" not 'assets' or anything else. Looks like a lot of learning resources are out of date? – Rin and Len Sep 12 '21 at 14:16
  • 3
    I am getting error file not supported. 'URL scheme "file" is not supported'. – Vineesh TP Sep 16 '21 at 03:33
  • Can you access files in the local filesystem using fetch? Perhaps outside the repo itself? – sayandcode Jun 30 '22 at 13:21
29

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
  • 6,611
  • 8
  • 49
  • 75
15

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 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!'))
Community
  • 1
  • 1
patelarpan
  • 7,188
  • 2
  • 20
  • 25
  • Compared to the other answers there is no server needed to fetch. Path to json file in the same dir as the script with fetch is needed, but no server. – Timo Apr 21 '22 at 06:14
12

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
  • 574
  • 5
  • 10
5

A simple solution to your issue is using the Live Server extension, which is available for Visual Studio Code.

  • Please share more details. Are you sure this is a good idea? Should every user of the application install VSCode first to make the application usable? – Nico Haase Jun 13 '23 at 08:56
2

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,481
  • 2
  • 28
  • 53
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
  • 581
  • 3
  • 8
1

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
  • 718
  • 10
  • 24
1

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.
  • 96
  • 4
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
  • 1,035
  • 1
  • 7
  • 17
0

To fetch local files, a good alternative:

npm install file-fetch
  • to read a file:
const fileFetch = require('file-fetch')
    
fileFetch('./public/user.json').then((res) => {         
  res.body.pipe(process.stdout)   
})

See doc

Siya Mzam
  • 4,655
  • 1
  • 26
  • 44
Andre Dias
  • 41
  • 2
0

Try to construct a loop server with your folder. just go to that folder and code:

python -m http.server -b localhost 8080

You can go to 127.0.0.1:8080 and have a simple web server.

If you have index.html in the current folder it shows this file, if not it shows you the list of files in the current folder