#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. Спасибо!