我正在创建一个产品页面,以卡片的形式显示所有可用的产品。 我想要一个功能,每当用户单击可用产品卡中的任何产品卡时,都会向服务器发出请求以打开包含完整产品详细信息的产品展示页面。我尝试了一些方法来做到这一点,但没有一个效果很好。
产品卡代码是
<div class="product-display-c">
<div class="product-card-holding-c">
<!-- -->
<% for (let i=0; i < data.length; i++) {%>
<div id="<%= data[i].id%>" class="product-card-c">
<div class="product-image-c">
<img class="product-card-image" src="<%= data[i].images[0]%>"
alt="random image" />
</div>
<div class="product-detail-c">
<p class="product-name">
<%= data[i].p_name%>
</p>
<p class="product-sp">Rs. <%= data[i].selling_price%>
</p>
<p class="product-mrp">M.R.P: Rs. <span>
<%= data[i].mrp%>
</span> </p>
<p class="product-discount">
<%= data[i].mrp - data[i].selling_price%> off
</p>
<p class="product-quality">Quality verified</p>
</div>
</div>
<% }%>
</div>
</div>
此代码根据从数据库接收的数据创建卡片。
之后,我创建了一个 JavaScript 代码来向服务器发送请求,以打开包含完整产品详细信息的产品展示页面。代码就像
document.querySelectorAll('.product-card-c').forEach((div) => {
div.addEventListener('click', function(event) {
console.log(event.target.closest('.product-card-c').id);
const selectedId =event.target.closest('.product-card-c').id;
fetch(`/products/${selectedId}`)
.then(response => console.log(response.text()))
});
});
此代码将单击的卡的 ID 发送到服务器。处理这个问题的服务器端代码就像
app.get('/products/:id', async function(req, res) { try { const selectedId = await db.query(
从产品中选择 * WHERE id=${req.params.id}); res.render("productshowcase.ejs", {product :selectedId.rows}); } catch (err) { console.log(err); } });
我不知道问题是什么,但当我点击卡片时没有任何反应。
虽然当我尝试使用 url localhost:3000/products/2 点击浏览器 url 部分时服务器响应,服务器打开产品展示页面,但没有应用 CSS,并且控制台中出现很多错误,例如 “无法加载资源:服务器响应状态为 404(未找到) 超值-trademart.png:1 无法加载资源:服务器响应状态为 404(未找到) header.js:1
Failed to load resource: the server responded with a status of 404 (Not Found)
1:1 拒绝执行来自“http://localhost:3000/products/jscript/header.js”的脚本,因为其 MIME 类型(“text/html”)不可执行,并且启用了严格的 MIME 类型检查。 类别2.jpg:1
Failed to load resource: the server responded with a status of 404 (Not Found)"
我完全陷入困境。谁能帮我找出错误在哪里。预先感谢。
我尝试寻找正确的方法向服务器发送请求,但未能找到正确的方法
EJS 是一个服务器端模板引擎,这意味着 HTML 是在服务器上创建的,并且通常作为 HTTP 响应发送回来。您想要做的是发出一个获取请求,该请求将获取呈现的 HTML 并将其存储为文本,当您执行
.then(response => console.log(response.text()))
时。之后什么也没有发生。 HTML 不会神奇地将自身附加到 DOM 或替换页面上现有的 HTML。
使用 fetch 时,通常会从服务器获取数据(通常为 JSON),并且您可以从该 JSON 有效负载循环遍历 is 属性并将 HTML 元素附加/替换到 DOM。您需要编写代码来做到这一点。或者,您可以只发送一个 url 作为响应,然后重定向浏览器以导航到新的 url。
如果坚持使用 EJS,我的诚实建议是
选项1:
扭曲
<a>
标签中的每张卡片,并将每个产品的 id
附加到 href
属性。这样,当您的用户单击卡片时,浏览器会向 GET
发送标准 /products/:id
请求并进行适当重定向。
这意味着您可以删除所有
document.querySelectorAll('.product-card-c').forEach
代码。
一个例子是:
<div class="product-display-c">
<div class="product-card-holding-c">
<!-- -->
<% for (let i=0; i < data.length; i++) {%>
<a href="/products/<%= data[i].id%>"> <!-- add this a tag -->
<div id="<%= data[i].id%>" class="product-card-c">
<div class="product-image-c">
<img class="product-card-image" src="<%= data[i].images[0]%>" alt="random image" />
</div>
<div class="product-detail-c">
<!-- rest of your code -->
</div>
</div>
</a>
<% }%>
</div>
</div>
选项2:
不要更改任何 HTML 代码,而不是发送获取请求,而是使用您的
click
处理程序导航到新的 url,如下所示:
document.querySelectorAll('.product-card-c').forEach((div) => {
div.addEventListener('click', function(event) {
console.log(event.target.closest('.product-card-c').id);
const selectedId =event.target.closest('.product-card-c').id;
window.location.assign(`http://localhost:3000/products/${selectedId}`); //< add this
});
});