我是 webdev 的新手,如果这是一个愚蠢的问题,我深表歉意。我正在使用 Node.js、Express 和 EJS,我正在尝试制作一个简单的天气应用程序来根据邮政编码显示天气。检索和显示温度一切正常。然而,在理想情况下,由于温度检索大约需要 3-5 秒,用户会在过渡期间看到一个加载页面,然后在过程结束时看到温度。我正在尝试这样做,但我正在努力处理加载页面和显示温度的页面之间的转换。
我目前获取温度的方法包括将输入的邮政编码传递给 javascript 函数 getTemperature,如下所示:
app.js(功能)
const express = require('express');
const bodyParser = require('body-parser');
const temperature = require('./temperature')
const path = require('path');
const app = express();
const port = 3000;
app.set('views',path.join(__dirname,'views'));
app.set('view engine', 'ejs');
app.use(bodyParser.urlencoded({extended:false}));
app.get('/', function(req, res) {
console.log("LOG: GET request");
res.render('pages/index', {output: "None"});
});
app.post('/',(req, res)=>{
const {zipcode} = req.body;
console.log("LOG: Received POST request with zip code " + zipcode);
temperature.getTemperatureFromZipcode(res, zipcode);
})
app.listen(port, () => {
console.log(`Listening on port ${port}`)
})
temperature.js(功能)
function getTemperatureFromZipcode(res, zipcode) {
// code omitted, finds the temperature via multiple API queries
res.render('pages/index', {output: temperature});
一切正常。但是,为了实现我制作加载页面的目标,我想在 app.js 中做这样的事情,当第一个请求发出时我在其中提供加载页面,然后我自己发出一个 POST 请求来完成以下工作获取温度 - 像这样:
app.js 更改(不工作)
const jsdom = require('jsdom');
const dom = new jsdom.JSDOM("");
const jQuery = require('jquery')(dom.window);
// repeated code omitted
app.post('/',(req, res)=>{
const {zipcode} = req.body;
console.log("LOG: Sending POST request with zip code " + zipcode);
res.render('pages/index', {output: "Loading"});
jQuery.ajax({
url: '/request',
type: 'POST',
contentType: 'application/json',
data: JSON.stringify({"zipcode": zipcode }),
success: function(response){ console.log( response ); }
});
})
app.post('/request',(req, res)=> {
console.log("LOG: Received POST request");
const {zipcode} = req.body.zipcode; // this may be incorrect, but the code never got here so it's also irrelevant
temperature.getTemperatureFromZipcode(res, zipcode); // makes a res.render call
})
然而,当我尝试这个时,第一个日志(发送帖子请求)看起来很好,但我没有看到第二个。似乎根本没有发出请求,因为当我检查我的网站并查看“网络”选项卡时,我只看到第一个请求。我还尝试将代码移动到客户端(即在呈现加载页面时在客户端触发 ajax 调用),但这也没有用,与上面的行为相同。
因此,我的问题是: a) 为什么这不起作用? (以我自己的理解) b) 什么是更好的选择?接受任何和所有建议。这是我觉得有更多用例的东西,而不仅仅是我想做的,所以我会很感激任何见解
提前致谢!
我自己想出来了——感谢 Mike Kamermans 的建议(我会在另一个项目中研究它!)并感谢 Phil 让我更多地研究前端——这就是答案:)
本质上,我将其更改为在初始 POST 请求时呈现加载页面,并将邮政编码保存在服务器中。然后加载页面发出 ajax post 请求(因此请求来自前端),并在调用 getTemperature 的后端接收到先前保存的邮政编码。然后 getTemperature 将温度发送回正在加载的页面,页面编辑 HTML 以包含新温度。
相关代码:
app.js 更新
// repeated code omitted
app.post('/',(req, res)=>{
const {zipcode} = req.body;
console.log("LOG: Received zip code through POST request: " + zipcode)
console.log("LOG: Rendering loader page");
app.locals.zipcode = zipcode;
console.log("LOG: Set global zip code to " + zipcode);
res.render('pages/loader', {output: "Loading!"});
})
app.post('/request',(req, res)=> {
console.log("LOG: Making request for zip code " + app.locals.zipcode);
temperature.getTemperature(res, app.locals.zipcode);
})
temperature.js
function getTemperature(res, zipcode) {
// make some API calls to get the temperature
res.status(200).send(temperature);
}
loader.ejs 头
<head>
<%- include('../partials/head'); %>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
$.ajax({
url: '/request',
type: 'POST',
cache: false,
data: {zipcode: "DONE"},
success: function(data){
document.querySelector("#output").innerHTML = data;
}
, error: function(jqXHR, textStatus, err){
console.log('ERROR: text status '+textStatus+', err '+err)
}
})
});
</script>
</head>
我之前尝试时,来自前端的 POST 请求不起作用的原因是因为我没有在前端包含 jquery。
我发现这篇文章对进行此更改非常有帮助 - 值得一试:How to change front-end html using node.js