Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature]: 希望可以在任何地方引用当前请求的headers,cookie #6728

Open
Zach889977 opened this issue Jan 13, 2025 · 4 comments
Open

Comments

@Zach889977
Copy link

这个功能解决了什么问题?

如果能够实现随时随地获取headers和cookie等,可以在loader和init之外的地方做很多事情。

Image Image

拿上面的场景举例,因为无法在loader和init钩子外获取cookie和headers,我不得不单独在middleware中提前创建ofetch或者axios实例,并且把当前绑定在当前的请求上下文中,那么会有一个问题,就是所有我需要使用这个fetch实例的地方,都要从loader中去触发,并且该把实例传过去。

Image

你期望的 API 是什么样子的?

参照next.js。

Image

nextjs通过借助asyncLocalstorage使cookies,headers等动态并且属于request上下文的变量或者对象有了对外导出,有了全局可访问的能力。

如果我们也能够从@modern-js/runtime/server或者@modern-js/runtime中引用当前request上下文所属的cookie和headers,就可以写出这样的代码。

Image
@Zach889977
Copy link
Author

Image

尝试了在middleware和afterMatch中去使用asyncLocalstorage,但是getStore返回undefined,应该是后续的中间件不包含loader的逻辑。

@Zach889977
Copy link
Author

Image

在loader中倒是可

Image 尝试了在middleware和afterMatch中去使用asyncLocalstorage,但是getStore返回undefined,应该是后续的中间件不包含loader的逻辑。

enableHandleWeb设置为true,依然不能在middleware和afterMatch中进行一步同步.
只能在loader中runWith

@zllkjc
Copy link
Member

zllkjc commented Jan 20, 2025

这里和 Next.js 还是有些不同的,Next.js 是默认 SSR 的,并且不考虑降级的问题。Modern.js 这边希望在 SSR 失败的时候,用户的代码仍然能在浏览器端运行,因此没有在任意地方都提供获取 cookie 的 AI。

但是组件内是可以获取的,Modern.js 提供了同构的 API:useRuntimeContext()

这里因为安全问题 Modern.js 里也做了限制:

  • 浏览器端可以获取的 cookie 只有 document.cookie 的值,服务端可以获取到所有 cookie
  • 浏览器端能获取到的 headers 需要通过 ssr.unsafeHeaders 配置,服务端可以获取到所有 header

下面是一个简单的配置文件和 layout.tsx 的代码,你可以参考:

import { appTools, defineConfig } from '@modern-js/app-tools';

export default defineConfig({
  runtime: {
    router: true,
  },
  server: {
    ssr: {
      unsafeHeaders: ['host'],
    },
  },
  plugins: [
    appTools({
      bundler: 'rspack',
    }),
  ],
});
import { useRuntimeContext } from '@modern-js/runtime';
import { Outlet } from '@modern-js/runtime/router';

const Layout = (): JSX.Element => {
  const { context } = useRuntimeContext();
  console.log(context.request.cookie);
  console.log(context.request.headers);

  return (
    <div>
      <Outlet />
    </div>
  );
};

export default Layout;

@lanmingle
Copy link

总觉得自动降级会影响性能,不能指定,不过 Modern.js 用 CSR 比较好。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants