Не удается установить заголовки после их отправки клиенту ошибка (узел/Экспресс-нуб, другие решения, похоже, не работали или не понимали их))

#javascript #node.js #express

Вопрос:

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

Это приложение Node/Express, в котором я пытаюсь практиковаться, где я использую API для получения долготы и широты из поля поиска, а затем использую эти данные ответа API для использования другого API, который использует долготу и широту для получения данных о погоде. У меня есть другое приложение, в котором я статически закодировал широту и долготу, и все работает нормально. Но у меня есть вложенные вызовы API и новый запрос post.

Однако я получаю эту ошибку «Ошибка [ERR_HTTP_HEADERS_SENT]: Не удается установить заголовки после их отправки клиенту», когда я пытаюсь отобразить представление. Когда я протестировал и удалил второй вложенный вызов API, он сработал, или, если я взял второй res.render, он, казалось, работал.

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

В идеале мне нужно получить данные из вложенного вызова API, «weatherDataResponse», данные для представления res.render. У меня он работает сам по себе, но когда я ввел /post и вызов API верхнего уровня, он не работает.

Код:

 function latLongInfo(results) {
  let obj = {
    method: 'GET',
    url: 'https://forward-reverse-geocoding.p.rapidapi.com/v1/forward',
    params: {
      street: '',
      city: results.city,
      state: results.state,
      postalcode: results.zip,
      country: 'USA',
      'accept-language': 'en',
      polygon_threshold: '0.0'
    },
    headers: {
      'x-rapidapi-key': rapidApiKey,
      'x-rapidapi-host': 'forward-reverse-geocoding.p.rapidapi.com'
    }
  }
  return obj
};

app.get('/', function(req, res) {
  res.render('index', { title: 'idk' });
});

app.post('/getweather', (req, res, next) => {
    const cityWeatherSearch = req.body.cityWeatherSearch
    next();
    axios.request(latLongInfo(parseLatLongSearch(cityWeatherSearch)))
    .then(function (response) {
      const getLatLongInfoResponse = response.data[0]
      console.log(getLatLongInfoResponse)
      if (Object.keys(getLatLongInfoResponse).length < 1) {
      
        res.render('invalidweather', { title: 'Invalid Results' });
      }
      else {
        let lat = getLatLongInfoResponse.lat, lon = getLatLongInfoResponse.lon;
        let latLonString = `${lat},${lon}`;
        const getWeatherInfo = axios.get(`https://api.pirateweather.net/forecast/${pirateWeatherKey}/${latLonString}`)
        axios.all([getWeatherInfo]).then(axios.spread((...responses) => {
          const weatherDataResponse = responses[0].data;
          console.log(weatherDataResponse)
          res.render('weather', { title: 'Weather Results' });
        })).catch(errors => {
          console.error(errors);
        })
      }
    })
    .catch(function (error) {
      console.log(error)
    })  
    res.end()

    
  })
 

Комментарии:

1. Почему вы звоните next (), если затем отвечаете на запрос? Похоже, в этом может быть проблема.

2. @AlexisTyler, о, это не имело никакого значения. Я удалил и попытался разместить next() в местах, я думал, что они должны перейти от чтения ответов на другие вопросы.

3. next() нужно вызывать только в том случае, если этот обработчик запроса не обрабатывает запрос, и вы хотите перейти к следующему обработчику. Для стандартного запроса вам не нужно его вызывать.

4. @AlexisTyler спасибо вам за эту информацию, я не был на 100% уверен в том, что она сделала, поэтому я определенно использовал ее неправильно!

Ответ №1:

Попробуйте что-нибудь в этом роде. Похоже next() , что звонок вызывает здесь проблемы. Я также немного переработал асинхронный материал, чтобы он был более читабельным.

 function latLongInfo(results) {
  let obj = {
    method: 'GET',
    url: 'https://forward-reverse-geocoding.p.rapidapi.com/v1/forward',
    params: {
      street: '',
      city: results.city,
      state: results.state,
      postalcode: results.zip,
      country: 'USA',
      'accept-language': 'en',
      polygon_threshold: '0.0'
    },
    headers: {
      'x-rapidapi-key': rapidApiKey,
      'x-rapidapi-host': 'forward-reverse-geocoding.p.rapidapi.com'
    }
  }
  return obj
};

app.get('/', function(req, res) {
  res.render('index', { title: 'idk' });
});

app.post('/getweather', async (req, res, next) => {
    try {
        const cityWeatherSearch = req.body.cityWeatherSearch;
        const response = await axios.request(latLongInfo(parseLatLongSearch(cityWeatherSearch)));
        const getLatLongInfoResponse = response.data[0]
        console.log(getLatLongInfoResponse)

        if (Object.keys(getLatLongInfoResponse).length < 1) {
            res.render('invalidweather', { title: 'Invalid Results' });
            return;
        }

        const lat = getLatLongInfoResponse.lat;
        const lon = getLatLongInfoResponse.lon;
        const latLonString = `${lat},${lon}`;
        const getWeatherInfo = await axios.get(`https://api.pirateweather.net/forecast/${pirateWeatherKey}/${latLonString}`);
        const weatherDataResponse = getWeatherInfo.data;
        console.log(weatherDataResponse)
        res.render('weather', { title: 'Weather Results' });
    } catch (error) {
        console.log(error);
    }
});
 

Комментарии:

1. Похоже, это сработало. Я мог бы поклясться, что попробовал это и без следующего (). Хотя я не пытался синхронизировать app.post, я не был уверен, что это приемлемо для app.post. Спасибо!