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

推荐订阅源

T
The Blog of Author Tim Ferriss
S
Securelist
D
Docker
The Register - Security
The Register - Security
GbyAI
GbyAI
Recorded Future
Recorded Future
Engineering at Meta
Engineering at Meta
Stack Overflow Blog
Stack Overflow Blog
云风的 BLOG
云风的 BLOG
P
Proofpoint News Feed
罗磊的独立博客
博客园 - 【当耐特】
F
Full Disclosure
WordPress大学
WordPress大学
腾讯CDC
小众软件
小众软件
大猫的无限游戏
大猫的无限游戏
D
DataBreaches.Net
SecWiki News
SecWiki News
L
Lohrmann on Cybersecurity
I
InfoQ
MyScale Blog
MyScale Blog
量子位
Cyberwarzone
Cyberwarzone
博客园 - 三生石上(FineUI控件)
The Hacker News
The Hacker News
F
Fortinet All Blogs
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
Jina AI
Jina AI
博客园_首页
H
Help Net Security
K
Kaspersky official blog
酷 壳 – CoolShell
酷 壳 – CoolShell
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Webroot Blog
Webroot Blog
Blog — PlanetScale
Blog — PlanetScale
V
Vulnerabilities – Threatpost
Y
Y Combinator Blog
The Cloudflare Blog
P
Proofpoint News Feed
V
Visual Studio Blog
C
Cyber Attacks, Cyber Crime and Cyber Security
T
Tailwind CSS Blog
爱范儿
爱范儿
P
Privacy International News Feed
Security Archives - TechRepublic
Security Archives - TechRepublic
The GitHub Blog
The GitHub Blog
C
Cybersecurity and Infrastructure Security Agency CISA
B
Blog RSS 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),
  }),
);

未完待续...