时光绘梦集

返回首页
随机箴言:能轻易失去的,都是不值得的。

正文区域

用中间件设置防盗链


夏夜万年2026-11-10 16:18:34代码

最近,站点做出了不少改动。然后我在无意中查看pages的文档时,突然发现了一个好东西,就是中间件。

以前好像也听说过这种东西,但是从来没去关注过,也可能是我没用到,所以不了解。

然后这次看文档时,突然发现这个东西不错,主要是EO的边缘函数是有用量统计的,好像文档中没说这个配额,应该是不消耗额度吧。

之前想给自己的站点设置防盗链,一直没设,主要是EO的免费版,想设置什么规则,只有一个匹配条件,然后,要么匹配路径,要么匹配来源,就是不能同时设置。可以用边缘函数设置,但是这样每次被访问就会消耗每月的函数额度。而且据文档介绍,这个中间件比边缘函数好,启动几乎0延迟,总之好处多多。

这次发现了这个好东西,第一步先用它给自己的一个子站点设置了防盗链(有几首音乐)。

第一步,在站点根目录新建一个middleware.js文件。

2.代码如下

// 防盗链中间件:只保护 /MP3/ 目录下的文件
// 文档:https://pages.edgeone.ai/document/middleware
// 注意:EdgeOne Pages 只读项目根目录的 middleware.js

export function middleware(context) {
    const { request, next } = context;
    const url = new URL(request.url);

    const site = request.headers.get('Sec-Fetch-Site');
    // 站内发起:放行;跨站一律拒绝
    if (site === 'same-origin') return next();

    // 老浏览器不发 Sec-Fetch-Site,退回到 Referer 比主机名
    if (site === null) {
        const referer = request.headers.get('Referer');
        if (referer) {
            try {
                if (new URL(referer).host === url.host) return next();
            } catch {
                // Referer 是 about:client 之类的非法地址,当作非同站
            }
        }
    }

    return new Response('403 Forbidden: 该资源仅允许站内访问', {
        status: 403,
        headers: {
            'Content-Type': 'text/plain; charset=utf-8',
            'Cache-Control': 'no-store',
        },
    });
}

export const config = {
    matcher: ['/MP3/:path*'],
};

在这其中,export function middleware(context)用来导出规则,export const config用来导出匹配的目录。