我有一个小型应用程序,它询问用户他们的城市并返回当前的天气数据。当用户单击“获取天气”功能时,它会从 OpenWeatherMap api 中提取 Json 并将其返回给用户。截至目前,它刷新页面并显示数据。我需要更改什么,以便在您更改城市时异步加载而不是刷新页面?
Server.js(快速路由)
const express = require('express');
const bodyParser = require('body-parser');
const weatherFunctions = require('./functions/weatherFunctions.js')
const PORT = process.env.PORT || 5000
const app = express()
app.use(express.static('public'));
app.use(bodyParser.urlencoded({ extended: true }));
app.set('view engine', 'ejs')
app.get('/', (req, res) => {
res.render('index', {weather: null, error: null});
})
app.post('/', weatherFunctions.getWeather)
app.listen(PORT, () => console.log(`Listening on ${ PORT }`))
weatherFunctions.js
const request = require('request');
const apiKey = '28af81603ac21f0fe4c75478dad21818';
function currentWeather(req, res) {
let city = req.body.city;
let url = `http://api.openweathermap.org/data/2.5/weather?q=${city}&units=imperial&appid=${apiKey}`
request(url, function (err, response, body) {
if (err) {
res.render('index', {
weather: null,
error: 'Error, please try again'
});
} else {
let weather = JSON.parse(body)
if (weather.main == undefined) {
res.render('index', {
weather: null,
error: 'Error, please try again'
});
} else {
let weatherText = `It's ${weather.main.temp} degrees in ${weather.name}! `;
weatherText += `The low for today will be ${weather.main.temp_min} degrees with a high of ${weather.main.temp_max}`;
res.render('index', {
weather: weatherText,
error: null
}); //passes parameters for ejs to read
}
}
});
}
module.exports = {
getWeather: currentWeather
};
索引.ejs
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Simple Weather</title>
<link rel="stylesheet" type="text/css" href="/css/style.css">
<link href='https://fonts.googleapis.com/css?family=Open+Sans:300' rel='stylesheet' type='text/css'>
</head>
<body>
<div class="container">
<fieldset>
<form action="/" method="post">
<input name="city" type="text" class="ghost-input" placeholder="Enter a City" required>
<input type="submit" class="ghost-button" value="Get Weather">
</form>
<% if(weather !== null){ %>
<p><%= weather %></p>
<% } %>
<% if(error !== null){ %>
<p><%= error %></p>
<% } %>
</fieldset>
</div>
</body>
</html>
最佳答案
它让您耳目一新的原因是您正在服务器端渲染 HTML。您需要利用 XMLHttpRequest (aka XHR) 。您可以使用名为 fetch
的 XHR 包装器这使得使用 XHR 变得更加容易。
使用浏览器获取 API 数据,然后使用该数据修改 DOM,称为“客户端渲染”。
例如,如果您打开浏览器控制台,并将以下代码粘贴到其中,您将看到如何从浏览器发送请求并获取数据(这是客户端渲染的基础):
fetch(`https://api.openweathermap.org/data/2.5/weather?q=New York&units=imperial&appid=28af81603ac21f0fe4c75478dad21818`).then(res => res.json()).then(data => console.log(data));
请参阅以下示例:
document
.getElementById("getWeather")
.addEventListener("click", () => {
handleGetWeather();
});
async function handleGetWeather() {
const apiKey = "28af81603ac21f0fe4c75478dad21818";
const locationEl = document.getElementById("location");
const weatherDataEl = document.getElementById("weatherData");
const results = await currentWeather(locationEl.value, apiKey);
weatherDataEl.innerHTML = results;
}
async function currentWeather(location, apiKey) {
const city = location.replace(/\s\s+/g, ' '); // Replace multiple spaces with single space
if (city === "" || city === " ") return `<pre>Please enter a location!</pre>`;
let url = `https://api.openweathermap.org/data/2.5/weather?q=${city}&units=imperial&appid=${apiKey}`;
try {
const res = await fetch(url);
if (res.ok === false) {
return `<pre><i>Location '${encodeURIComponent(city)}' not found!</i></pre><br/><pre>Full Error: ${res.statusText}</pre>`;
}
const weather = await res.json();
const main = weather.main;
const t = Number(main.temp) >= 71.00 ? 'hot' : 'cold';
const min = Number(main.temp_min) >= 71.00 ? 'hot' : 'cold';
const max = Number(main.temp_max) >= 71.00 ? 'hot' : 'cold';
return `
<h1>
It's <span class="${t}">${main.temp}</span> degrees in ${weather.name}!
</h1>
<h1>
The low for today will be
<span class="${min}">${main.temp_min}</span>
degrees with a high of
<span class="${max}">${main.temp_max}</span>
</h1>
`;
} catch {
return `<pre><i>Error, please try again.</i></pre>`;
}
}
pre {
color: red;
margin-bottom: -15px;
}
.hot {
color: red;
}
.cold {
color: blue;
}
<input id="location" />
<button id="getWeather">Get Weather</button>
<div id="weatherData"></div>
关于javascript - 如何使用express和node进行异步调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59228892/