如何從服務器端獲取HTML代碼到客戶端詳解
随着服务器开发的发展,在需要从服务器取模板时,需要把HTML代码发给客户端。在这篇文章里,我们将考虑主要方式。这些方法都会用到javascript,但其实质也能用其他编程语言表达。
让我们直接来看看代码,看看这在项目中如何实现。
🌍 前端在这里我们可以突出几种从服务器获取HTML的方法。所有这些方法都将基于向服务器发送请求。在JavaScript中有一个fetch
构造,可以让你做类似的事情(XMLHTTPRequest
不再被考虑,因为它已经过时了。如果你不需要支持旧浏览器,我建议你不要使用它)。
要从服务器加载HTML,我们可以使用HMPL,这是一种用于从服务器向客户端展示UI的模板语言。HMPL的工作原理是发送可自定义的请求到服务器,然后将这些请求处理成可以直接使用的HTML。
让我们先安装 hmpl-js
作为依赖包,然后创建一个脚本文件。
npm i hmpl-js # 安装 hmpl-js 模块
全屏模式,退出全屏
然后,我们引入 compile
函数。
import { compile } from "hmpl-js";
// 定义模板函数
const templateFn = compile(
`{{ src: "/api/getForm" }}`
);
// 将模板函数的结果赋值给变量 form
const form = templateFn();
全屏切换
结果是:
form = {
response: <template><h1>想联系我们的朋友们, 请看下面的表单</h1><form action="/submit" method="...</template>,
status: 200
}
全屏模式 退出全屏
在这里,我们得到一个模板
,表单就存在这个模板里。你也可以将一个div
元素添加到页面中,这样你就可以没有模板
,而是直接在div
中得到表单内容。
import { compile } from "hmpl-js";
const templateFn = compile(
`<div>{{ src: "/api/getForm" }}</div>`
);
const form = templateFn();
/*
form = {
response: <div><h1>联系我们吧</h1><form...</div>,
status: 200
}
*/
全屏 退出全屏
这样一来,我们马上就能拿到一个可以加到DOM里的元素。
另外,如果你能为该项目点个赞支持一把那就最好了!谢谢 ❤️!
✅ 好处:
-
重用性: 你可以重复使用一次创建的模板任意多次,就像使用一个
class
的实例一样。 -
简单明了的语法: HTML 引入了一个请求对象,其语法与原生代码完全相同,因此在使用 JavaScript 时,你可以轻松复制代码,因为该模块在处理 JSON5 时也能正常工作。
-
高度可定制的: 模板语言提供了广泛的需求自定义功能。与类似项目(如 HTMX)不同,你可以几乎完全掌控流程。
-
轻量级: 它的重量很轻,约15千字节,几乎不会对项目造成任何影响。
- 浏览器兼容: 现代的 JavaScript API,例如
fetch()
,在大多数浏览器中得到了广泛支持,确保了大多数情况下的兼容性,无需额外的 polyfills。
❌ 缺点有:
-
依赖关系: 通过添加一个模块,你将相应的代码添加到项目中,这些代码占用特定数量的字节。
- 在旧版浏览器中遇到的现代 API 限制: 虽然特性如
fetch()
被广泛支持,但仍可能需要为旧版浏览器添加 polyfill,不像一些库会自动处理向后兼容性。
首先,你需要创建一个脚本文件,然后在这个文件里向服务器发送请求。文件中的代码大概如下所示:
main.js
fetch('/api/getForm') // HTML 片段的 URL
.then(response => {
if (!response.ok) {
throw new Error(`HTTP 错误!状态码:${response.status},`);
}
return response.text();
})
.then(html => {
console.log(html); // 输出 HTML
})
.catch(error => {
console.error('获取 HTML 时出错:', error); // 错误信息
});
全屏模式 退出全屏
在这里我们从服务器获取响应,如果成功,则调用 text
函数来接收响应。值得注意的是,存在 HTTP 状态码 100(主要为重定向),因此在处理这些状态码时也需要更加小心,并添加适当的错误处理。
更多详情可以在这里查看HTTP状态:here。
✅ 优势:
-
轻量且无依赖: 使用纯JavaScript代码避免了对额外库或框架的需求,缩小了项目的体积和外部依赖。
-
完全掌控: 纯JavaScript(原生JS)让你完全掌控实现细节,让你可以按需处理网络请求、响应及DOM操作。
-
浏览器兼容: 像
fetch()
这样的现代 JavaScript API 在大多数现代浏览器中得到广泛支持,保证在大多数情况下无需额外的 polyfills 即可兼容。 - 学习机会:通过使用原始JavaScript,可以帮助开发者理解基础概念,比如HTTP请求、响应以及DOM,从而提高他们的编程能力。
❌ ⚠️ 缺点:
-
冗余代码:
纯 JavaScript 通常需要更多的样板代码,相比之下,像 Axios 这样的库或 React 这样的框架可以更简洁地处理请求和更新。 -
处理错误
如果没有使用高级库提供的抽象功能,处理错误(例如网络问题、无效响应)可能会变得复杂且重复繁琐。 -
缺乏抽象:
处理超时、重试或并发请求等任务通常需要手动实现,这可能会很繁琐且容易出错。 - 可维护性:
仅用JavaScript编写的代码在大型项目中可能更难维护,因为由于其冗长和缺乏标准化模式。
(Note: There is a slight redundancy in "因为由于" which can be corrected to simply "因为" for better fluency.)
Corrected version:
-
可维护性:
仅用JavaScript编写的代码在大型项目中可能更难维护,因为其冗长和缺乏标准化模式。 - 尽管
fetch()
这样的特性广泛支持,但可能仍需为旧版浏览器添加polyfills,而一些库会自动处理向后兼容性。
考虑到后端的情况,值得注意的是,在客户端我们必须接收模板。为此,我们可以创建一个 API 路由来获取服务器上的 HTML。首先,我们来创建需要发送给客户端的 HTML 代码。
form.html
<h1>联系我们</h1>
<form action="/submit" method="POST">
<label for="name">名字:</label>
<input type="text" id="name" name="name" required><br><br>
<label for="email">邮箱:</label>
<input type="email" id="email" name="email" required><br><br>
<label for="message">留言:</label><br>
<textarea id="message" name="message" rows="4" cols="50" required></textarea><br><br>
<button type="submit">发送</button>
</form>
切换到全屏模式 退出全屏
这是一个简单的联系表。如果它不仅可以在服务器端修改,也可以在客户端修改,而且不仅限于一个网站,还可以在多个相关网站上修改,那就更好了。
要做到这一点,我们可以创建一个API路由,通过它来接收服务器返回的HTML。我们的后端将采用Node.js。我们将使用Express.js框架来完成。它是目前最受欢迎的框架之一,非常适合我们正在处理的问题。首先,我们需要指定处理HTML的控制器:
const express = require("express");
const expressRouter = express.Router();
const path = require("path");
const formController = (req, res) => {
res.sendFile(path.join(__dirname, "../form.html"));
};
expressRouter.use("/getForm", formController);
全屏 全屏退出
然后,你需要将其连接到 /api
,以避免将常规网站路由与后端路由混在一起。express.js 应用程序有一个入口点,所有初始化都在这里进行。这里我们需要导入控制器。
app.js
const express = require("express");
const path = require("path");
const bodyParser = require("body-parser");
const cors = require("cors");
const PORT = 8000;
const app = express();
const routes = require("./routes/formController");
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cors({ origin: true, credentials: true }));
app.set(express.static(path.join(__dirname, "src")));
app.use("/api", routes);
app.listen(PORT);
切换到全屏模式
退出全屏
之后,我们应该在网站上有一个 /api/getForm
路径,可以向其发送 GET
请求。响应中会收到 HTML 内容。
根据实际情况,你可以选择第一种方法或第二种方法。在第二种方法中,你对整个过程有完全掌控,但这种方法仍然不太适合当你需要处理多个组件时,因为你必须自己建立逻辑,这会花费时间。
感谢大家的阅读!希望这篇文章能帮到大家!
GIF
共同學習,寫下你的評論
評論加載中...
作者其他優質文章