惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

阮一峰的网络日志
阮一峰的网络日志
D
Darknet – Hacking Tools, Hacker News & Cyber Security
S
Schneier on Security
The Last Watchdog
The Last Watchdog
Cyberwarzone
Cyberwarzone
S
Securelist
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
C
Cyber Attacks, Cyber Crime and Cyber Security
L
Lohrmann on Cybersecurity
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
博客园 - 司徒正美
The Cloudflare Blog
V
V2EX
博客园_首页
博客园 - 聂微东
Vercel News
Vercel News
人人都是产品经理
人人都是产品经理
G
GRAHAM CLULEY
T
Tenable Blog
Last Week in AI
Last Week in AI
Y
Y Combinator Blog
L
LINUX DO - 最新话题
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
SecWiki News
SecWiki News
博客园 - 三生石上(FineUI控件)
S
Secure Thoughts
N
News | PayPal Newsroom
T
The Blog of Author Tim Ferriss
The GitHub Blog
The GitHub Blog
T
Troy Hunt's Blog
博客园 - 【当耐特】
Forbes - Security
Forbes - Security
H
Hacker News: Front Page
A
About on SuperTechFans
B
Blog RSS Feed
Engineering at Meta
Engineering at Meta
MongoDB | Blog
MongoDB | Blog
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
罗磊的独立博客
D
DataBreaches.Net
P
Privacy & Cybersecurity Law Blog
Schneier on Security
Schneier on Security
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Google DeepMind News
Google DeepMind News
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Jina AI
Jina AI
D
Docker
P
Proofpoint News Feed

無名小栈

如何实现一个自动化友链流程 | 無名小栈 使用 acme.sh 生成泛域名 SSL 证书 如何给博客添加一个跳转提示页 | 無名小栈 关于 DailyHotApi 的重构 | 無名小栈 Curve 主题文档 - 快速开始 | 無名小栈 Markdown-it 如何自定义文中的标签 | 無名小栈 Curve 主题文档 - 标签使用 | 無名小栈 去除了无意义的 PWA | 無名小栈 关于我开发的那些项目,和这个博客 | 無名小栈
初识 Hono( 一 ) | 無名小栈
無名 · 2024-03-15 · via 無名小栈

文章摘要 FakeGPT

加载中...|

此内容根据文章生成,并经过人工审核,仅用于文章内容的解释与总结 投诉

缘由 ​

最近看到 DIYgod 大佬写的一篇文章:一个六岁开源项目的崩溃与新生,文中提到了他用 Homo Hono 框架替换了 RSSHub 项目原本使用的 Koa 框架。巧了,我正好也有几个项目在使用 Koa 框架,但是这也是第一次听说这个新框架,于是就打算学习一下看看,能不能用 Hono 框架来替换掉这个已经不太活跃的老框架。

安装 ​

安装是必不可少的,在这里使用 pnpm 来安装:

bash

pnpm create hono my-app

在选择完基本信息后,进入安装目录安装依赖并运行:

bash

cd my-app
pnpm install
pnpm dev

程序将会默认运行在 3000 端口,若出现占用情况,可自行更换端口。( 3000 端口可太容易被占用了 )

请求和响应 ​

Hono 基本上支持所有的请求类型,并且可返回多种类型的响应。

基本类型 ​

常用的请求类型比如 GETPOSTPUTDELETE 请求:

js

import { serve } from "@hono/node-server";
import { Hono } from "hono";

const app = new Hono();

// GET
app.get("/", (c) => c.text("Hello Hono!"));

// POST
app.post("/", (c) => c.text("Hello Hono!"));

// PUT
app.put("/", (c) => c.text("Hello Hono!"));

// DELETE
app.delete("/", (c) => c.text("Hello Hono!"));

同时,Hono 也支持链式路线,这样能使代码更加清晰:

js

app
  .get("/test", (c) => {
    return c.text("GET /test");
  })
  .post((c) => {
    return c.text("POST /test");
  })
  .put((c) => {
    return c.text("PUT /test");
  });
  .delete((c) => {
    return c.text("DELETE /test");
  });

携带参数 ​

在使用请求时,通常会携带参数,比如你想发送一个附带路径参数的 GET 请求:

http

GET 127.0.0.1:3000/posts/114514?username=homo

那么你可以使用 req.param() 方法来获取路径参数,req.query() 方法来获取携带参数:

js

app.get("/posts/:id", (c) => {
  // 获取路径参数
  const id = c.req.param("id");
  // 获取携带参数
  const username = c.req.query("username");
  return c.text(`获取由 ${username} 用户发表的 ID 为 ${id} 的文章`);
  // 获取由 homo 用户发表的 ID 为 114514 的文章
});

返回 HTML ​

Hono 也支持返回 HTML 类型的响应,你需要先定义一个 JSX 组件,例如:

jsx

const View = () => {
  return (
    <html>
      <body>
        <h1>Hello Hono!</h1>
      </body>
    </html>
  );
};

export default View;

然后便可在接口处返回:

js

app.get("/home", (c) => {
  return c.html(Home());
});

中间件 ​

CORS ​

CORS 算是后端服务不可缺少的设置了,负责允许设置跨域资源共享( CORS )的响应头,以允许跨域请求。

js

import { Hono } from "hono";
import { cors } from "hono/cors";

const app = new Hono();

// 应用到所有路由
app.use("*", cors());

// 单独对某个接口设置
app.use(
  "/api2/*",
  cors({
    origin: "http://example.com",
    allowHeaders: ["X-Custom-Header", "Upgrade-Insecure-Requests"],
    allowMethods: ["POST", "GET", "OPTIONS"],
    exposeHeaders: ["Content-Length", "X-Kuma-Revision"],
    maxAge: 600,
    credentials: true,
  }),
);

CORS 参数

参数类型默认值描述
originstring | string[] | (origin: string) => string*Access-Control-Allow-Origin 的值。可以是一个确定的字符串,一个字符串数组,或是一个回调函数,如 origin: (origin) => (origin.endsWith('.example.com') ? origin : 'http://example.com')
allowMethodsstring[]['GET', 'HEAD', 'PUT', 'POST', 'DELETE', 'PATCH']Access-Control-Allow-Methods 的值,标明允许哪些 HTTP 请求方法。
allowHeadersstring[][]Access-Control-Allow-Headers 的值,标明在请求中允许设置哪些 HTTP 头部
maxAgenumber-Access-Control-Max-Age 的值,指定预检请求的结果能够被缓存多长时间。
credentialsboolean-Access-Control-Allow-Credentials 的值,标明是否允许请求的凭证模式(如Cookies)
exposeHeadersstring[][]Access-Control-Expose-Headers 的值,列出哪些头部可以被客户端 JavaScript 代码访问

CSRF ​

CSRF 是一种攻击手段,攻击者通过欺骗用户的浏览器,让其代为发起恶意请求,通常是在用户不知情的情况下,使用用户的登录身份执行一些操作。CSRF 攻击发生在第三方网站上,但是请求是发给受信任站点的,所以请求会带上用户的认证信息,如 Cookie。为了防止 CSRF 攻击,开发人员需要确保安全地验证用户请求的来源。

js

import { Hono } from "hono";
import { csrf } from "hono/csrf";

const app = new Hono();

// 使用 origin 选项指定允许的来源
app.use(csrf({ origin: "myapp.example.com" }));

// 使用 origin 选项指定多个允许的来源
app.use(
  csrf({
    origin: ["www.example.com", "development.example.com"],
  }),
);

同时还可以用函数的方式来进行匹配:

DANGER

强烈建议验证协议以确保与 $ 匹配,请永远不要使用 * 进行匹配

js

app.use(
  "*",
  csrf({
    // 使用正则表达式检查来源 URL 是否匹配指定的模式
    origin: (origin) => /https:\/\/(\w+\.)?myapp\.example\.com$/.test(origin),
  }),
);

未完待续...