0

0

EJS渲染错误:‘Cannot GET’问题的根源与解决方案

聖光之護

聖光之護

发布时间:2025-10-17 12:07:17

|

1127人浏览过

|

来源于php中文网

原创

EJS渲染错误:'Cannot GET'问题的根源与解决方案

本文深入探讨了在express.js应用中ejs文件渲染失败,出现“cannot get /store.html”错误的原因。核心问题在于对express路由与ejs视图引擎工作机制的误解,特别是url与服务器端路由的匹配,以及视图文件渲染时的正确调用方式。教程将详细指导如何正确配置和访问ejs模板,确保动态内容能够顺利呈现。

引言

在开发基于Node.js和Express框架的Web应用时,EJS(Embedded JavaScript)作为一种流行的模板引擎,常用于生成动态HTML内容。然而,开发者在初次使用或配置不当的情况下,可能会遇到EJS文件无法正确渲染,浏览器显示“Cannot GET /your-file.html”或类似错误。这通常不是EJS模板文件本身的问题,而是对Express路由、视图引擎配置以及客户端请求方式的理解偏差所致。

问题分析:'Cannot GET /store.html'

当您尝试通过浏览器访问 http://localhost:3000/store.html 时,如果服务器返回“Cannot GET /store.html”错误,这表明Express服务器未能找到与该URL路径匹配的路由处理器,或者未能将该请求视为对静态文件的请求。

在提供的代码示例中,开发者期望渲染一个名为 store.ejs 的模板文件。然而,通过 store.html 路径访问时,服务器的响应表明它正在尝试寻找一个名为 store.html 的静态文件,或者一个处理 /store.html 路径的特定路由,但两者均未找到。这揭示了以下几个关键误解:

  1. 路由与文件扩展名: Express路由 (app.get('/store', ...)) 定义的是一个URL路径,而不是一个文件路径。客户端请求的URL应该与定义的路由路径匹配,而不是直接指向服务器上的模板文件(例如 store.ejs)或带有.html扩展名的文件。
  2. EJS视图引擎的工作方式: 当Express配置了EJS作为视图引擎后,res.render() 方法会根据视图名称(不带扩展名)自动查找对应的EJS文件,并使用EJS引擎进行渲染。客户端不需要知道或指定模板文件的扩展名。
  3. 静态文件服务: app.use(express.static('public')) 配置用于提供静态资源(如CSS、JS、图片等),这些文件通常直接存储在 public 目录下,并通过其原始路径访问。EJS模板文件不属于静态资源,它们需要通过视图引擎进行处理。

Express.js与EJS视图引擎工作原理

为了正确渲染EJS模板,我们需要理解Express如何协同EJS工作。

1. 视图引擎配置

在Express应用中,您需要明确告知Express使用哪个模板引擎以及模板文件存放在何处。

app.set('views', path.join(__dirname, 'views')); // 指定模板文件存放的目录
app.set('view engine', 'ejs');                   // 设置EJS为默认的视图引擎
  • app.set('views', ...):告诉Express所有模板文件都位于 views 目录下。
  • app.set('view engine', 'ejs'):告诉Express当调用 res.render() 方法时,默认使用EJS引擎来处理模板,并且在查找模板文件时,会自动添加 .ejs 扩展名。

2. 路由定义与视图渲染

路由定义了服务器如何响应特定的HTTP请求(例如GET、POST)以及对应的URL路径。

app.get('/store', (req, res) => {
    // ... 业务逻辑 ...
    res.render('store', { items: JSON.parse(data) }); // 渲染名为 'store' 的EJS模板
});
  • app.get('/store', ...):这个路由处理器会在客户端请求 http://localhost:3000/store 时被触发。
  • res.render('store', ...):此方法会指示Express查找 views 目录下的 store.ejs 文件,使用EJS引擎处理它,并将处理结果作为HTML响应发送给客户端。注意,这里传递给 render 方法的视图名称是 store,不包含 .ejs 扩展名。

3. 静态资源与动态视图

  • 静态资源: 通过 app.use(express.static('public')),Express会将 public 目录下的文件作为静态资源提供。例如,如果 public 目录下有一个 style.css 文件,客户端可以通过 http://localhost:3000/style.css 访问。
  • 动态视图: EJS模板文件(例如 views/store.ejs)是动态视图,它们需要通过 res.render() 方法和视图引擎进行处理,而不是直接通过URL访问。

解决方案:正确配置与访问EJS模板

结合上述原理,解决“Cannot GET /store.html”问题的关键在于确保客户端请求的URL与服务器端定义的路由相匹配,并且服务器端使用正确的 res.render() 方法来处理EJS模板。

代码示例与解析

以下是您提供的Express应用代码,我们将对其关键部分进行解析:

Pixlr
Pixlr

Pixlr是一款2008年推出的在线图片编辑和AI图片处理工具,目前已推出AI 图像生成器、AI 生成填充、AI 删除背景、AI 删除对象和 AI 图像扩展等现代 AI 工具。

下载
if (process.env.NODE_ENV !== 'production') {
    require('dotenv').config()
}

const stripeSecretKey = process.env.STRIPE_SECRET_KEY
const stripePublicKey = process.env.STRIPE_PUBLIC_KEY

const express = require('express')
const path = require('path')
const app = express()
const fs = require('fs')
const stripe = require('stripe')(stripeSecretKey)

// 1. EJS视图引擎配置
app.set('views', path.join(__dirname, 'views')) // 指定模板文件目录为当前目录下的'views'文件夹
app.set('view engine', 'ejs')                   // 设置EJS为视图引擎

// 2. 中间件配置
app.use(express.json())         // 解析JSON格式的请求体
app.use(express.static('public')) // 提供'public'目录下的静态文件

// 3. 路由定义
app.get('/store', (req, res) => { // 定义一个GET请求的路由,路径为 '/store'
    fs.readFile('items.json', (error, data) => {
        if (error) {
            res.status(500).end()
        } else {
            // 4. 渲染EJS模板
            res.render('store', { // 渲染名为 'store' 的EJS模板,Express会自动查找 'views/store.ejs'
                items: JSON.parse(data)
            })
        }
    })
})

app.listen(3000, () => {
    console.log('Server is running on port 3000');
})

关键修正点:

根据上述代码,您的Express应用已经正确配置了EJS视图引擎和路由。因此,问题出在客户端的访问方式上。

  • 错误访问方式:

    • http://localhost:3000/store.html (错误,服务器没有处理此路径的路由,也不是静态文件)
    • http://localhost:3000/store.ejs (错误,EJS模板不应直接通过URL访问)
  • 正确访问方式:

    • 您应该通过浏览器访问 http://localhost:3000/store。

当您访问 http://localhost:3000/store 时:

  1. Express会匹配到 app.get('/store', ...) 这个路由。
  2. 路由处理器中的 res.render('store', ...) 会被调用。
  3. 由于 view engine 被设置为 ejs,Express会在 views 目录下查找 store.ejs 文件。
  4. EJS引擎会处理 store.ejs 模板,将 items 数据注入其中,生成最终的HTML。
  5. 生成的HTML内容将作为响应发送给客户端。

注意事项与常见问题

  1. EJS包安装: 确保您的项目中已经安装了EJS包。如果没有,请运行 npm install ejs。
  2. 文件路径: 确认 store.ejs 文件确实位于项目根目录下的 views 文件夹中。例如,如果您的 app.js 在项目根目录,那么 views/store.ejs 路径是正确的。
  3. 路由冲突: 检查是否有其他路由或静态文件服务与 /store 路径冲突。
  4. 服务器重启: 每次修改服务器端代码后,请确保重启Node.js应用以使更改生效。

总结

在Express.js中使用EJS模板时,理解路由、视图引擎配置和客户端请求之间的关系至关重要。避免直接在URL中包含 .html 或 .ejs 扩展名来访问动态模板。正确的做法是:

  • 通过 app.set('view engine', 'ejs') 和 app.set('views', 'your_views_directory') 配置视图引擎。
  • 通过 app.get('/your_route', ...) 定义路由。
  • 在路由处理器中使用 res.render('your_template_name', data) 来渲染模板(模板名称不带扩展名)。
  • 客户端通过与路由匹配的URL(例如 http://localhost:3000/your_route)来访问。

遵循这些原则,您将能够有效地利用EJS和Express构建功能强大的动态Web应用。

相关专题

更多
js获取数组长度的方法
js获取数组长度的方法

在js中,可以利用array对象的length属性来获取数组长度,该属性可设置或返回数组中元素的数目,只需要使用“array.length”语句即可返回表示数组对象的元素个数的数值,也就是长度值。php中文网还提供JavaScript数组的相关下载、相关课程等内容,供大家免费下载使用。

536

2023.06.20

js刷新当前页面
js刷新当前页面

js刷新当前页面的方法:1、reload方法,该方法强迫浏览器刷新当前页面,语法为“location.reload([bForceGet]) ”;2、replace方法,该方法通过指定URL替换当前缓存在历史里(客户端)的项目,因此当使用replace方法之后,不能通过“前进”和“后退”来访问已经被替换的URL,语法为“location.replace(URL) ”。php中文网为大家带来了js刷新当前页面的相关知识、以及相关文章等内容

372

2023.07.04

js四舍五入
js四舍五入

js四舍五入的方法:1、tofixed方法,可把 Number 四舍五入为指定小数位数的数字;2、round() 方法,可把一个数字舍入为最接近的整数。php中文网为大家带来了js四舍五入的相关知识、以及相关文章等内容

706

2023.07.04

js删除节点的方法
js删除节点的方法

js删除节点的方法有:1、removeChild()方法,用于从父节点中移除指定的子节点,它需要两个参数,第一个参数是要删除的子节点,第二个参数是父节点;2、parentNode.removeChild()方法,可以直接通过父节点调用来删除子节点;3、remove()方法,可以直接删除节点,而无需指定父节点;4、innerHTML属性,用于删除节点的内容。

470

2023.09.01

JavaScript转义字符
JavaScript转义字符

JavaScript中的转义字符是反斜杠和引号,可以在字符串中表示特殊字符或改变字符的含义。本专题为大家提供转义字符相关的文章、下载、课程内容,供大家免费下载体验。

388

2023.09.04

js生成随机数的方法
js生成随机数的方法

js生成随机数的方法有:1、使用random函数生成0-1之间的随机数;2、使用random函数和特定范围来生成随机整数;3、使用random函数和round函数生成0-99之间的随机整数;4、使用random函数和其他函数生成更复杂的随机数;5、使用random函数和其他函数生成范围内的随机小数;6、使用random函数和其他函数生成范围内的随机整数或小数。

989

2023.09.04

如何启用JavaScript
如何启用JavaScript

JavaScript启用方法有内联脚本、内部脚本、外部脚本和异步加载。详细介绍:1、内联脚本是将JavaScript代码直接嵌入到HTML标签中;2、内部脚本是将JavaScript代码放置在HTML文件的`<script>`标签中;3、外部脚本是将JavaScript代码放置在一个独立的文件;4、外部脚本是将JavaScript代码放置在一个独立的文件。

652

2023.09.12

Js中Symbol类详解
Js中Symbol类详解

javascript中的Symbol数据类型是一种基本数据类型,用于表示独一无二的值。Symbol的特点:1、独一无二,每个Symbol值都是唯一的,不会与其他任何值相等;2、不可变性,Symbol值一旦创建,就不能修改或者重新赋值;3、隐藏性,Symbol值不会被隐式转换为其他类型;4、无法枚举,Symbol值作为对象的属性名时,默认是不可枚举的。

535

2023.09.20

苹果官网入口直接访问
苹果官网入口直接访问

苹果官网直接访问入口是https://www.apple.com/cn/,该页面具备0.8秒首屏渲染、HTTP/3与Brotli加速、WebP+AVIF双格式图片、免登录浏览全参数等特性。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

10

2025.12.24

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Sass 教程
Sass 教程

共14课时 | 0.7万人学习

Bootstrap 5教程
Bootstrap 5教程

共46课时 | 2.6万人学习

CSS教程
CSS教程

共754课时 | 16.1万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号