Запрос на загрузку в локальный файл не работает

Я пытаюсь сделать запрос в локальный файл, но я не знаю, когда я пытаюсь сделать на моем компьютере, показать мне ошибку. Возможно ли сделать выборку в файл внутри вашего проекта?

 // 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)
   })
 }

12 ответов

Решение

Вы пытаетесь передать статический файл командой извлечения, которая по своей природе требует, чтобы файл обслуживался сервером. Чтобы решить эту проблему, у вас есть несколько вариантов, доступных для вас. Я собираюсь обрисовать в общих чертах два, которые обычно предлагаются для такой вещи:

  • Используйте Node.js и что-то вроде expressjs для размещения вашего собственного сервера, который обслуживает файл, который вы хотите получить. Хотя эта процедура может потребовать больше усилий и времени, она, безусловно, более настраиваема и является хорошим способом узнать и понять, как работает выборка из серверной части.
  • Используйте что-то вроде веб-сервера Chrome, чтобы легко настроить очень простой сервер для обслуживания вашего файла в локальной сети. Используя этот метод, вы практически не контролируете, что вы можете делать с указанным веб-сервером, но вы можете быстро и легко создать прототип своего веб-приложения. Однако я сомневаюсь, что есть способ перенести этот метод в производство.

Наконец, есть и другие варианты, в которых вы можете загрузить один или несколько файлов онлайн и извлечь их с внешнего URL-адреса, однако это может быть не оптимальной стратегией.

Попробуйте поместить свой JSON-файл в общую папку следующим образом:

общественности /movies.json

а затем получить с помощью

fetch('./movies.json')

или же

fetch('movies.json')

Я испытывал ту же проблему ранее. Когда я помещаю файл json в общую папку, проблема решается. При использовании fetch React обычно читает файлы ресурсов / ресурсов в общей папке.

Ваш JSON-файл должен обслуживаться сервером, поэтому вам нужен экспресс-сервер (или любой другой). В этом примере мы используем, используя экспресс.

Примечание: вы также можете скачать git repo

Файл App.js

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!'))

Я столкнулся с той же ошибкой, и я внес два изменения в свой код, чтобы избавиться от нее. Во-первых, вам не нужен экспресс-сервер для обслуживания ваших файлов, вы можете читать данные из локального файла json внутри вашей общей папки в каталоге create-response-app.

      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()
  },[])

Во-первых, как предлагается в некоторых из приведенных выше ответов, убедитесь, что ваш json-файл находится внутри общей папки, а параметр пути внутри функции выборки правильный, как указано выше. Относительные пути у меня не работали. Во-вторых, установите заголовки, как показано. Удаление части заголовков из моего вызова выборки все еще давало мне эту ошибку.

Простое решение - использовать расширение живого сервера (если вы используете vs code)

Я заставил его работать очень простым способом - на самом деле не нужен экспресс / веб-сервер. Просто делать:

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

и используйте данные json следующим образом (скажем, если это JsonArray):data.map(movie...

Сделайте это в App.js или какой-то другой класс, расширяющий React.Component,

Скажите, что у меня есть следующий файл 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>

При доступе к файлу в firefox через file://... я получаю следующую ошибку:

  Cross-Origin Request Blocked:....

Когда я следил за ошибкой в ​​firefox, я получил следующее объяснение

Запросы CORS могут использовать только схему URL-адресов HTTPS, но URL-адрес, указанный в запросе, относится к другому типу. Это часто происходит, если URL-адрес указывает локальный файл с использованием URL-адреса file:///.

Чтобы решить эту проблему, просто убедитесь, что вы используете URL-адреса HTTPS при отправке запросов с участием CORS, таких как XMLHttpRequest, Fetch API, веб-шрифты (@font-face), текстуры WebGL и таблицы стилей XSL.

Итак, насколько я понимаю, нам просто нужно получить доступ к test.html через HTTP. Самым простым способом решения этой проблемы был простой http-сервер на Python. В терминале.

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

Затем в браузере:

http://localhost:8000/test.html

Чтобы получить локальные файлы, хорошая альтернатива:

      npm install file-fetch
  • чтобы прочитать файл:
      const fileFetch = require('file-fetch')
    
fileFetch('./public/user.json').then((res) => {         
  res.body.pipe(process.stdout)   
})

См. документ

Попробуйте создать циклический сервер с вашей папкой. просто перейдите в эту папку и введите код:

      python -m http.server -b localhost 8080

Вы можете пойти в127.0.0.1:8080и иметь простой веб-сервер.

Если у вас естьindex.htmlв текущей папке отображается этот файл, если нет, отображается список файлов в текущей папке

Мой подход заключается в том, чтобы использовать экспресс-генератор для настройки быстрого локального сервера, затем запустить ngrok (бесплатный уровень подходит) и указать вашему приложению URL-адрес, который он создает. Это дает вам преимущество, позволяя вам легко проверить выборку в симуляторе iOS или эмуляторе Android, а также на устройстве, не привязанном к вашему компьютеру. Кроме того, вы также можете отправить URL людям, тестирующим ваше приложение. Конечно, им нужно было бы вручную ввести этот URL, чтобы приложение могло установить его в качестве конечной точки выборки.

Ошибка

      Unexpected token < in JSON at position 0

поступает из HTML-файла, который возвращается в случае неудачного запроса. Первым элементом (в позиции 0) HTML-файла обычно является '<'. Вместо JSON выполняется попытка чтения HTML-файла.

Вы можете найти возвращенный HTML-файл в Inspect Tool -> Network -> Erroneous file, отмеченный красным -> Reponse. Там вы можете увидеть, в чем заключается конкретная ошибка. Пример сообщения об ошибке

Чтобы исправить ошибку для меня, это помогло переместить файл, который нужно импортировать, в папку Public моего проекта React, а затем импортировать его вот так из файла в папке src: fetch('dataTemplate.json')

Вы можете разместить свой json-файл в общей папке. В вашем компоненте React вы можете использовать userEffect (). В этом случае Express.js не нужен.

React.useEffect(() => { 
   fetch("./views/util/cities.json")
      .then(function(response) {
        return response.json();
      })
      .then(function(myJson) {
        console.log(myJson);
      });
  });
Другие вопросы по тегам