简体   繁体   English

Next.js中如何修改请求头

[英]How to modify request headers in Next.js

I have a need to add a header to each request to the server.我需要向服务器的每个请求添加一个 header。

I do it this using _midleware like this:我这样做使用_midleware是这样的:

export async function middleware(req: NextRequest): Promise<NextResponse> {
    req.headers.append('x-custom-header', '1337');
    return NextResponse.next();
}

If I do console.log(req.headers) I see that the request header has been added:如果我执行console.log(req.headers) ,我会看到已添加请求 header:

BaseHeaders [Headers] {
    [Symbol(map)]: {
      accept: [ '*/*' ],
      'accept-encoding': [ 'gzip, deflate, br' ],
      'accept-language': [ 'en-GB,en-US;q=0.9,en;q=0.8' ],
      'cache-control': [ 'no-cache' ],
      connection: [ 'keep-alive' ],
      cookie: ...,
      host: ...,
      pragma: [ 'no-cache' ],
      referer: ...,
      ...,
      'x-custom-header': [ '1337' ]
    }
  }

However, this does not modify the request: there is no request header in the browser.但是,这并没有修改请求:浏览器中没有请求header。

Why is the request not modified?为什么请求没有修改? Are there alternative ways to modify request headers in Next.js?是否有其他方法可以修改 Next.js 中的请求标头?

Looks like starting from Next.js v13.0.0 it is now possible to modify request headers: https://nextjs.org/docs/advanced-features/middleware#setting-headers看起来从 Next.js v13.0.0 开始现在可以修改请求标头: https://nextjs.org/docs/advanced-features/middleware#setting-headers

Here's a code snippet from the documentation:这是文档中的代码片段:

 // middleware.ts import { NextResponse } from 'next/server' import type { NextRequest } from 'next/server' export function middleware(request: NextRequest) { // Clone the request headers and set a new header `x-hello-from-middleware1` const requestHeaders = new Headers(request.headers) requestHeaders.set('x-hello-from-middleware1', 'hello') // You can also set request headers in NextResponse.rewrite const response = NextResponse.next({ request: { // New request headers headers: requestHeaders, }, }) // Set a new response header `x-hello-from-middleware2` response.headers.set('x-hello-from-middleware2', 'hello') return response }

Interesting question actually, since although I've done a lot of work on SPA architectures I hadn't looked into nextjs and its SSR behavior.实际上是一个有趣的问题,因为虽然我在 SPA 架构上做了很多工作,但我还没有研究过 nextjs 及其 SSR 行为。

CUSTOM HEADERS AND CROSS SITE REQUEST FORGERY自定义标头和跨站点请求伪造

A good angle for solving your problem is to think about other common use cases for custom headers and look for a nextjs solution.解决您的问题的一个好角度是考虑自定义标头的其他常见用例并寻找 nextjs 解决方案。 A security related one is to send a Cross Site Request Forgery custom request header, eg example-csrf , in data changing API requests.与安全相关的一种方法是在数据更改 API 请求中发送Cross Site Request Forgery自定义请求标头,例如example-csrf

When I searched for nextjs ways to do that I found this next-csrf library and I suspect it will enable you to solve your problem.当我搜索 nextjs 的方法时,我发现了这个next-csrf 库,我怀疑它可以帮助您解决问题。 From what I can see, it works like this, though I think you'll understand the nextjs specifics better than me:据我所知,它是这样工作的,尽管我认为你会比我更了解 nextjs 的细节:

  • The middleware class runs on the website when a request is first received, and creates the request header value当第一次收到请求时, 中间件类在网站上运行,并创建请求标头值

  • The value is then provided to React components, which will run in the browser:然后将该值提供给 React 组件,该组件将在浏览器中运行:

import { getCsrfToken } from '../lib/csrf';

function MyApp({ Component, pageProps }) {
  return <Component {...pageProps} csrfToken={getCsrfToken()} />
}
  • Also I think the React views you write can then send that value from the browser if required:另外我认为如果需要,您编写的 React 视图可以从浏览器发送该值:
const response = await fetch('/api/protected', {
    'headers': {
        'XSRF-TOKEN': csrfToken,
    }
});

There are some issues / feedback posted on the CSRF GitHub repo also - reading some of those may help you with your own solution. CSRF GitHub repo 上也发布了一些问题/反馈 - 阅读其中一些可能会帮助您找到自己的解决方案。

ARCHITECTURE THOUGHTS架构思想

It is interesting looking at this, since I know nextjs is highly respected and enables better SEO etc. It also reminds me of older website technologies where developers often struggled, due to having to switch between client side and server side code.看这个很有趣,因为我知道 nextjs 备受推崇并且可以实现更好的 SEO 等。它也让我想起了开发人员经常遇到的旧网站技术,因为必须在客户端和服务器端代码之间切换。 Being in control of data requests is an important technical foundation.控制数据请求是一个重要的技术基础。

Out of interest, at Curity we have some code resources focused on SPA security, CDN deployment and developer experience, in case any of this is ever useful, for future reference.出于兴趣,在 Curity,我们有一些专注于 SPA 安全性、CDN 部署和开发人员体验的代码资源,以备将来参考。 We do not use SSR currently, but we may want to say more about SSR use cases in future:我们目前不使用 SSR,但我们可能想在未来多谈谈 SSR 用例:

This is what worked for me.这对我有用。 The header is changed in middleware and reflected in getServerSideProps.标头在中间件中更改并反映在 getServerSideProps 中。

export async function middleware(request: NextRequest) : Promise<NextResponse> {
    const response = NextResponse.next()
    response.headers.append("key", "value")
    return response
}


//inside page
export const getServerSideProps = wrapper.getServerSideProps(store => async (context) => {
    //the headers are changed here
    console.log(context.res.getHeaders())
    return {
      props: {}
    }
  }
});

You can add custom headers in a similar way you would by adding security headers , by using headers in your next.config.js :您可以通过在next.config.js中使用headers头,以与添加安全标头类似的方式添加自定义标头:

// next.config.js

// You can choose which headers to add to the list
// after learning more below.
const securityHeaders = []

module.exports = {
  async headers() {
    return [
      {
        // Apply these headers to all routes in your application.
        source: '/:path*',
        headers: securityHeaders,
      },
    ]
  },
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM