Запрос на загрузку в локальный файл не работает
Я пытаюсь сделать запрос в локальный файл, но я не знаю, когда я пытаюсь сделать на моем компьютере, показать мне ошибку. Возможно ли сделать выборку в файл внутри вашего проекта?
// 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);
});
});