如何在js 13下获取服务器组件上的url路径名

How can I get the url pathname on a server component next js 13

提问人:Updater XD 提问时间:2/6/2023 最后编辑:Updater XD 更新时间:11/17/2023 访问量:31074

问:

所以基本上我在应用程序目录中有一个服务器组件,我想获取路径名。我尝试使用 window.location 来做到这一点,但它不起作用。 有什么办法可以做到这一点吗?

javascript next.js 路径 路由器 react-server-components

评论

0赞 evolutionxbox 2/6/2023
我不认为服务器端存在窗口。考虑使用 path 模块和 dirname?
0赞 Updater XD 2/6/2023
我已经知道那个窗口不存在,但无论如何都要感谢
0赞 artifii 5/31/2023
在文档“在服务器组件中使用 cookies() 或 headers() 将在请求时选择整个路由进入动态渲染 nextjs.org/docs/app/building-your-application/rendering/”中找到了一些有关 @and-yet-it-compiles 的答案的信息。

答:

19赞 Björn 2/6/2023 #1

看看 https://github.com/vercel/next.js/issues/43704,pauliusuza 解决了这个问题

您可以使用中间件进行解决

import { NextResponse } from 'next/server';

export function middleware(request: Request) {

  // Store current request url in a custom header, which you can read later
  const requestHeaders = new Headers(request.headers);
  requestHeaders.set('x-url', request.url);

  return NextResponse.next({
    request: {
      // Apply new request headers
      headers: requestHeaders,
    }
  });
}

然后从根布局内部使用它:

import { headers } from 'next/headers';

export default function RootLayout() {
  const headersList = headers();
  // read the custom x-url header
  const header_url = headersList.get('x-url') || "";
}

希望能有所帮助

评论

3赞 Ankit Jain 5/16/2023
不过,这里有一个警告。这将完全禁用页面的 SSG。更多信息可以在 nextjs.org/docs/app/building-your-application/rendering/ 找到...
4赞 KBeDev 5/20/2023
就我而言,我使用标头获取了路径名x-invoke-path
0赞 reactor 6/12/2023
我header_url被记录为空
1赞 Soheil Bakhtyari 10/12/2023
注意:在生产中不起作用,我不知道其他的,如linux或...
18赞 and yet it compiles... 5/23/2023 #2

或者,我认为一个更简单的解决方案是使用请求中已经存在的 Next 标头,例如 or .hostrefer

例:

import { headers } from 'next/headers';

export default function Navbar() {
    const headersList = headers();
    const domain = headersList.get('host') || "";
    const fullUrl = headersList.get('referer') || "";

    console.log(fullUrl);
}
2赞 yoty66 6/14/2023 #3

这将找到路径名,假设你有一个 referer cookie:

import { headers } from 'next/headers';

const domain = headersList.get('host') || "";
const fullUrl = headersList.get('referer') || "";
const [,pathname] = fullUrl.match( new RegExp(`https?:\/\/${domain}(.*)`))||[];

console.log(pathname);
12赞 Amos 7/9/2023 #4

这对我有用

import { headers } from "next/headers";

const headersList = headers();
const domain = headersList.get("x-forwarded-host") || "";
const protocol = headersList.get("x-forwarded-proto") || "";
const pathname = headersList.get("x-invoke-path") || "";

评论

0赞 userlond 10/27/2023
使用此方法时缺少搜索参数
3赞 nordic70 11/17/2023
这在 v14.0.2 中不再有效。你用的是什么版本?
1赞 Soheil Bakhtyari 10/2/2023 #5

在应用程序的 src 目录中创建一个middleware.ts,它将负责应用程序的 URL,我添加了一些其他有用的属性,例如适合调用内部 API 的 origin 和用于访问组件路径的路径名; 请注意,它只能在服务器组件内部使用

import { NextResponse } from 'next/server';

export function middleware(request: Request) {

const url = new URL(request.url);
const origin = url.origin;
const pathname = url.pathname;
const requestHeaders = new Headers(request.headers);
requestHeaders.set('x-url', request.url);
requestHeaders.set('x-origin', origin);
requestHeaders.set('x-pathname', pathname);

return NextResponse.next({
    request: {
        headers: requestHeaders,
    }
});
}

并在您的服务器组件中使用它,例如

import { headers } from "next/headers";

export default async function page() {

    const headersList = headers()
    const header_url = headersList.get('x-url') || "";
    const pathname = headersList.get('x-pathname');
    const origin_url = headersList.get('x-origin');

}
基于 https://github.com/vercel/next.js/issues/43704

0赞 Sobhan Jahanmard 10/26/2023 #6

这个答案几乎是正确的。使用带有 src 模式的应用程序目录,我意识到我需要更改如下所示的位置。middleware.ts

.
├── src
│   ├── app
│   └── middleware.ts
5赞 alisahindev 11/8/2023 #7

NextJS v14 服务器端获取路径名

 import { headers } from "next/headers";

 const heads = headers()

 const pathname = heads.get('next-url')

评论

0赞 Aiman Farhan 11/9/2023
谢谢你,先生。我的用例是根据 pathName 动态更改样式
0赞 nordic70 11/17/2023
在 Nextjs v14.0.2 中。此标头不可用。查看 github.com/vercel/next.js/issues/58542
0赞 nordic70 11/19/2023
@alisahindev 我不明白评论。但标头不再受支持。next-url