Я пытаюсь получить продукты по их ключу. В postman api работает нормально, но в forntend нет ответа. код backend

app.get('/foods/:key', (req, res) => {
    foodsCollection.find({ key: req.params.key }).toArray((err, documents) => {
      res.send(documents[0])
    })
  })

код фронтенда

const { key } = useParams()
  const [foodById, setFoodById] = useState({})

  useEffect(() => {
    fetch(`http://localhost:5000/foods/${key}`)
      .then((res) => res.json())
      .then((data) => {
        setFoodById(data)
      })
  }, [key])

This is the frontend page

Route page

Api is working

Not rendering in the frontend

Md Irtiza Hossain

Ответов: 3

Ответы (3)

Хотя вы добавили несколько изображений выше, не хватает самого важного, а именно того, в чем заключается проблема в Инструментах разработчика браузера. Вы должны увидеть какое-то сообщение на вкладке Консоль, а также на вкладке Сеть для этого конкретного запроса, если он действительно выполняется. Пока никто не увидит этого, будет очень трудно помочь в решении вашей проблемы.

Если вы еще не сделали этого, я рекомендую создать любое приложение react с помощью create-react-app (CRA). Это даст вам рабочее приложение, с которого можно начать. Вы можете игнорировать CORS проблемы, связанные с разработкой, при использовании CRA, добавив `прокси'': "http://localhost:5000", в ваш файл package.json, подробнее об этом методе смотрите здесь, но помните, что это работает только для локальной разработки. Вы также можете заставить Chrome игнорировать Web Security, запустив его с флагом --disable-web-security, например, chromium --disable-web-security, но это не очень хорошая идея, скорее способ быстро определить, есть ли у вас проблемы с CORS, поскольку Chrome маскирует некоторые проблемы как связанные с CORS, когда на самом деле это не так.

Я бы также предложил изменить ваш код выборки, чтобы использовать await, так что вместо этого вы будете иметь:

const response = await fetch(`http://localhost:5000/foods/${key}`);

if (!response.ok) {
  console.error(`Error message: ${response.statusText} ${response.status}`);
}

const result = response.json();
console.log(result);

Это не обязательно, но я всегда находил, что это гораздо легче читать, чем метод then/catch/finally.

Причина ошибки

Вам необходимо строкировать объект перед отправкой клиенту с помощью метода JSON.stringify(). Когда мы обмениваемся данными с веб-сервером, они должны быть строкой.

Решение:

Правильным способом отправки ответа клиенту будет обернуть весь API в блок try-catch и явно указывать HTTP Status Code вместе со строгированными данными в каждом ответе.

Примечание: Хотя код состояния 500 используется для обработки ошибок, вы должны выбрать его в соответствии с ситуацией использования.

app.get('/foods/:key', (req, res) => {
  try {
    /*
      rest of the code
    */

    foodsCollection.find({ key: req.params.key }).toArray((err, documents) => {
      if (err) {
        // 500 stands for internal server error
        return res.status(500).send(JSON.stringify('Here goes a meaningful error message!'));
      }

      // 200 stands for success
      res.status(200).send(JSON.stringify(documents[0]));
    });

    /*
      rest of the code
    */
  } catch (error) {
    // 500 stands for internal server error
    res.status(500).send(JSON.stringify('Here goes another meaningful error message!'));
  }
})

Проблема в том, что вы не установили CORS заголовки ответа в коде бэкенда. и вы используете разные порты в бэкенде и фронтенде (5000 и 3000), поэтому политика Same Origin Policy запрещает чтение удаленного ресурса, указывая, что запрос был заблокирован из-за нарушения правил безопасности CORS.

вам необходимо установить CORS-заголовки.

Вы можете установить пакет CORS npm и следовать его инструкциям, чтобы решить проблему следующим образом:

var express = require('express')
var cors = require('cors')
var app = express()

app.use(cors())
.
.
.

И еще одна проблема, которую я вижу, заключается в том, что вы поместили маршрут по умолчанию react-router перед указанным вами путем. Поэтому переместите <route path="*"> после <route path="/foods/:key">.

2022 WebDevInsider