稀土掘金 稀土掘金

Next.js 14中怎么使用 CORS

本文为翻译作品,原文链接: How to use CORS in Next.js 14

在深入研究 Next.js 中的 CORS 之前,让我们一起回顾一下总体思路,以建立牢固的基础认识。

跨源资源共享(或 CORS)是一种安全机制,用于保护网站免受跨源请求的影响。

简单来说,“来源”指的是除你自己的域以外的任何域。

此外,“来源”被正式定义如下:

<协议>://<域名>:<端口号>
端口号可以是可选的,例如 <协议>://<域名> 也足够了。

例如: www.example.com:443

请看下面的 CORS 操作,来源 x.com 尝试从来源 y.com 接收数据:

1.webp

🗣️ 词语解释:

  1. x.com 发送预请求(也就是 HTTP OPTIONS 请求)以请求来自 y.com 的数据。
  2. y.com 随后检查请求的 Headers
  3. 如果启用了 CORS Headers 且 y.com 在白名单中,则向 x.com 发送数据。
  4. 如果禁用了 CORS Headers,或者 y.com 不在白名单中,则不向 x.com 发送数据。

那么你可能会问:“什么是 CORS Headers?”

有四个主要 CORS Headers 需要了解:

  • Access-Control-Allow-Origin — 指定可以访问该资源的来源
  • Access-Control-Allow-Methods — 添加到预检响应中,以指示允许的 HTTP 方法,如 GET、POST、PUT 等
  • Access-Control-Allow-Headers — 在响应预检请求时返回,以指定当前请求中允许的 HTTP 头
  • Access-Control-Allow-Credentials — 指示浏览器是否应在跨来源请求中包含诸如 cookies 或 HTTP 认证的凭证

现在我们已经熟悉了 CORS,及其在网页开发中的应用,让我们将这些理解应用到 Next.js 的项目中。

在 Next.js 中启用 CORS 的 3 种方式

请确保通过在终端窗口运行以下命令创建一个新的 Next.js 14 应用程序:

npx create-next-app@latest

1. Next.js 配置 Headers

在你的应用程序根目录下的 next.config.js 文件中,你可以配置异步的 headers() 键,带有所需的 CORS Headers:

// next.config.js

/** @type {import('next').NextConfig} */
const nextConfig = {
    async headers() {
        return [
            {
                // 在这里,你可以使用正则表达式添加你的来源 URL。
                source: "<your-source-url(s)>",
                headers: [
                    { key: "Access-Control-Allow-Credentials", value: "true" },
                    // 在这里添加你的白名单来源
                    { key: "Access-Control-Allow-Origin", value: "<your-origin>" },
                    { key: "Access-Control-Allow-Methods", value: "GET,DELETE,PATCH,POST,PUT" },
                    { key: "Access-Control-Allow-Headers", value: "X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version" },
                ]
            }
        ]
    }
}

module.exports = nextConfig

注意:

  • 你可以使用路径正则表达式配置多个来源。例如,/api/:path* 将匹配所有 api 路径。
  • 你的来源将能够访问你的来源 URL API 数据;确保来源是可信任的。

2. 中间件

如果你需要在请求发送到你的来源之前应用 CORS Headers,则需要使用中间件。

在与你的 app/ 目录同级的位置,创建一个名为 middleware.ts 的文件,并使用以下模板代码:

// src/middleware.ts 或 src/middleware.js

// https://blog.logrocket.com/using-cors-next-js-handle-cross-origin-requests/

import { NextResponse } from "next/server";

export function middleware() {
    // 检索当前响应
    const res = NextResponse.next()

    // 向响应中添加 CORS Headers
    res.headers.append('Access-Control-Allow-Credentials', "true")
    res.headers.append('Access-Control-Allow-Origin', '<your-origin>')
    res.headers.append('Access-Control-Allow-Methods', 'GET,DELETE,PATCH,POST,PUT')
    res.headers.append(
        'Access-Control-Allow-Headers',
        'X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version'
    )

    return res
}

// 中间件只会应用于以下路由。
export const config = {
    matcher: '<your-source-url(s)>',
}

你现在可以通过配置 matcher 来适配这段代码,它指定了你的来源可以访问的 source-urls。

3. Vercel 配置文件

假设你在 Vercel 上托管你的 Next.js 应用程序,你还可以在 Next.js 项目的根目录下添加一个 vercel.json 文件,并按照以下方式自定义它:

// 类似于 next.config.js 方法,但使用不同的路径正则表达式语法(参见 vercel.json 文档)。

// https://vercel.com/docs/projects/project-configuration#headers

{
  "headers": [
    {

      "source": "<your-source-url(s)>",
      "headers": [
        { "key": "Access-Control-Allow-Credentials", "value": "true" },
        { "key": "Access-Control-Allow-Origin", "value": "<your-origin>" },
        { "key": "Access-Control-Allow-Methods", "value": "GET,DELETE,PATCH,POST,PUT" },
        { "key": "Access-Control-Allow-Headers", "value": "X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version" }
      ]
    }
  ]
}

针对多个端点调整 CORS 策略

目前,你只能为特定模式的来源(例如 api/:path*)追加 Headers。

但假设你需要为另一个特定来源或多个来源应用特定的 CORS Headers。

使用中间件允许多个来源:

import { NextResponse } from "next/server";

// 所有允许的来源列表
const allowedOrigins = [
  'http://localhost:3000', 
  'https://example-1.com', 
  'https://example-2.com', 
  // ...
  'https://example-99.com', 
];

export function middleware(req) {
    // 检索当前响应
    const res = NextResponse.next()

    // 从传入请求中检索 HTTP "Origin" headers
    req.headers.get("origin")

    // 如果来源是允许的一个,
    // 将其添加到 'Access-Control-Allow-Origin' headers
    if (allowedOrigins.includes(origin)) {
      res.headers.append('Access-Control-Allow-Origin', origin);
    }

    // 将剩余的 CORS Headers 添加到响应中
    res.headers.append('Access-Control-Allow-Credentials', "true")
    res.headers.append('Access-Control-Allow-Methods', 'GET,DELETE,PATCH,POST,PUT')
    res.headers.append(
        'Access-Control-Allow-Headers',
        'X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date, X-Api-Version'
    )

    return res
}

// 中间件只会应用于以下路由。
export const config = {
    matcher: '<your-source(s)',
}

使用 vercel.jsonnext.config.js 为额外的特定来源:

// next.config.js

/** @type {import('next').NextConfig} */
const nextConfig = {
    async headers() {
        return [
            {
                // 匹配所有 API 路径
                source: "/api/:path*",
                headers: [
                   // 为了简洁省略...
                ]
            },
            // 额外的特定来源:/api/special-data
            {
                source: "/api/special-data",
                headers: [
                    { key: "Access-Control-Allow-Credentials", value: "false" },
                    { key: "Access-Control-Allow-Origin", value: "https://example.com" },
                    { key: "Access-Control-Allow-Methods", value: "GET,DELETE,PATCH,POST,PUT" },
                    { key: "Access-Control-Allow-Headers", value: "Accept, Accept-Version, Content-Length, Content-MD5, Content-Type, Date" },
                ]
            }
        ]
    }
}

module.exports = nextConfig

总结

CORS 是一种重要的安全机制,它保护你的网站免受跨来源请求的侵害。使用本文介绍的三种方法,就可以正确为你的 Next.js 应用提升安全策略了。

玻璃钢生产厂家玻璃钢西瓜雕塑供应混凝土玻璃钢花盆模具重庆景区玻璃钢雕塑设计优质的景观玻璃钢雕塑南京玻璃钢卡通雕塑优惠玻璃钢元谋人雕塑株洲湖南玻璃钢雕塑品牌哪家好玻璃钢卡通人物雕塑工程贺州玻璃钢泡沫雕塑公司东莞人物玻璃钢雕塑安装地址玻璃钢人物雕塑翻模南京周年商场美陈小品系列玻璃钢雕塑厂家最新玻璃钢花盆图片湛江优惠的玻璃钢雕塑玻璃钢雕塑蝴蝶摆件达州市玻璃钢雕塑生产厂家玻璃钢飘带雕塑图片驻马店玻璃钢仿真雕塑广东玻璃钢雕塑摆件采购新乡玻璃钢雕塑定制营口市玻璃钢雕塑新密玻璃钢智能雕塑南宁玻璃钢雕塑批发沈阳商场美陈装饰西藏门头玻璃钢雕塑内蒙古玻璃钢小绵羊雕塑景观玻璃钢仿铜雕塑邯郸圣诞玻璃钢雕塑朔州玻璃钢雕塑专业雕塑厂家香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声单亲妈妈陷入热恋 14岁儿子报警汪小菲曝离婚始末遭遇山火的松茸之乡雅江山火三名扑火人员牺牲系谣言何赛飞追着代拍打萧美琴窜访捷克 外交部回应卫健委通报少年有偿捐血浆16次猝死手机成瘾是影响睡眠质量重要因素高校汽车撞人致3死16伤 司机系学生315晚会后胖东来又人满为患了小米汽车超级工厂正式揭幕中国拥有亿元资产的家庭达13.3万户周杰伦一审败诉网易男孩8年未见母亲被告知被遗忘许家印被限制高消费饲养员用铁锨驱打大熊猫被辞退男子被猫抓伤后确诊“猫抓病”特朗普无法缴纳4.54亿美元罚金倪萍分享减重40斤方法联合利华开始重组张家界的山上“长”满了韩国人?张立群任西安交通大学校长杨倩无缘巴黎奥运“重生之我在北大当嫡校长”黑马情侣提车了专访95后高颜值猪保姆考生莫言也上北大硕士复试名单了网友洛杉矶偶遇贾玲专家建议不必谈骨泥色变沉迷短剧的人就像掉进了杀猪盘奥巴马现身唐宁街 黑色着装引猜测七年后宇文玥被薅头发捞上岸事业单位女子向同事水杯投不明物质凯特王妃现身!外出购物视频曝光河南驻马店通报西平中学跳楼事件王树国卸任西安交大校长 师生送别恒大被罚41.75亿到底怎么缴男子被流浪猫绊倒 投喂者赔24万房客欠租失踪 房东直发愁西双版纳热带植物园回应蜉蝣大爆发钱人豪晒法院裁定实锤抄袭外国人感慨凌晨的中国很安全胖东来员工每周单休无小长假白宫:哈马斯三号人物被杀测试车高速逃费 小米:已补缴老人退休金被冒领16年 金额超20万

玻璃钢生产厂家 XML地图 TXT地图 虚拟主机 SEO 网站制作 网站优化