如果您想要服务器端 getInitialProps 中的主机名,您仍然可以从 req 获取它
Home.getInitialProps = async(context) => {
const { req, query, res, asPath, pathname } = context;
if (req) {
let host = req.headers.host // will give you localhost:3000
}
}
通过服务器端渲染(
getServerSideProps
),您可以使用context.req.headers.host
:
import type { GetServerSideProps, NextPage } from "next";
type Props = { host: string | null };
export const getServerSideProps: GetServerSideProps<Props> =
async context => ({ props: { host: context.req.headers.host || null } });
const Page: NextPage<Props> = ({ host }) => <p>Welcome to {host || "unknown host"}!</p>;
export default Page;
但是使用静态生成(
getStaticProps
),主机名不可用,因为没有请求从中获取它。一般来说,服务器不知道自己的公共主机名,因此您需要告诉它。使用 Next.js 环境变量,将其放入 .env.local
:
HOST=example.com
然后使用
process.env['HOST']
访问它:
import type { GetStaticProps } from "next";
export const getStaticProps: GetStaticProps<Props> =
async context => ({ props: { host: process.env['HOST'] || null }});
如果您想获得完整的网址:
import { useRouter } from 'next/router';
const { asPath } = useRouter();
const origin =
typeof window !== 'undefined' && window.location.origin
? window.location.origin
: '';
const URL = `${origin}${asPath}`;
console.log(URL);
您访问的位置
window
请确保添加检查,以便代码仅在浏览器上执行,而不会在 SSG 期间执行”
if (typeof window !== 'undefined') {
const hostname = window.location.hostname;
}
更新: 如果您在
basePath
中指定了 next.config.js
:
module.exports = {
basePath: 'https://www.example.com/docs',
}
然后使用
useRouter
,您可以访问基本路径:
import { useRouter } from 'next/router'
function Component() {
const router = useRouter();
console.log({ basePath: router.basePath});
// { basePath: 'https://www.example.com/docs' }
...
}
但是如果你有相对基本路径,那么你可以使用第一种方法
考虑这个包> next-absolute-url
import absoluteUrl from 'next-absolute-url'
const { origin } = absoluteUrl(req)
const apiURL = `${origin}/api/job.js`
如果您现在部署了 Next.js 应用程序,apiURL 将类似于
https://your-app.now.sh/api/job.js
。
但是,如果您在本地运行应用程序,则 apiURL 将改为
http://localhost:8000/api/job.js
。
根据此处提到的答案,您可以使用以下代码使用新的应用程序目录(用于服务器端组件)在 Next 13 中获取主机名:
import { headers } from 'next/headers';
export default function Home() {
const headersList = headers();
headersList.get('host'); // to get domain
headersList.get('next-url'); // to get url
return <div>....</div>
}
使用
typeof window !== 'undefined'
是安全的方法。 if (window) {}
会给你带来麻烦。
const hostname = typeof window !== 'undefined' && window.location.hostname ? window.location.hostname : '';
const origin = typeof window !== 'undefined' && window.location.origin ? window.location.origin : '';
使用上面的代码将为您提供客户端使用的前端/外部主机名/来源:
example.com
、www.example.com
、www.example.com:80
等,而不是localhost
之类的东西。 useRouter()
将返回服务器端主机名/来源(localhost
,localhost:3000
)
我相信你最好结合使用
useRouter
和 useEffect
钩子来做到这一点。就我而言,我想动态设置网页的 og:url
。这就是我所做的。我们将 router.pathname
作为依赖项,以便每次移动到不同页面时都会更新 ogUrl
。
import { useRouter } from "next/router";
import { useState, useEffect } from "react";
const MyComponent = () => {
const router = useRouter();
const [ogUrl, setOgUrl] = useState("");
useEffect(() => {
const host = window.location.host;
const baseUrl = `https://${host}`;
setOgUrl(`${baseUrl}${router.pathname}`);
}, [router.pathname]);
return <div></div>
}
您需要确保对
window.location.hostname
的访问仅发生在客户端,而不是在服务器端渲染期间(其中 window
不存在)。您可以通过将其移动到组件中的 useEffect
回调来实现这一点。
function Component() {
useEffect(() => {
console.log(window.location.hostname)
console.log(window.location.href) // Logs `http://localhost:3000/blog/incididunt-ut-lobare-et-dolore`
}, [])
// Remaining code of the component
}
这是我解决这个问题的方法,这也适用于 Next.js 13 App Router:
创建一个钩子,将其命名为use-origin.jsx(或.tsx),并将其添加到根目录中的/hooks文件夹中:
'use client'; // this is Next 13 App Router stuff
import { useEffect, useState } from "react";
export default function useOrigin() {
const [mounted, setMounted] = useState(false);
const origin = typeof window !== 'undefined' && window.location.origin ? window.location.origin : '';
useEffect(() => {
setMounted(true)
}, [])
if (!mounted) {
return null
}
return origin;
}
现在使用此钩子访问您的动态 BASE_URL 路由:
"use client";
import useOrigin from "@/hooks/use-origin"
export default function Test() {
const origin = useOrigin();
return (
<div>{origin}</div>
)
}
req.headers 是符号而不是对象,因此要获取值,请使用 get 方法
const host = req.headers.get("host"); // stackoverflow.com
使用添加到项目根目录的 middleware.js 文件可以让您访问主机名,并在需要时提供很大的灵活性来基于它执行操作。
https://nextjs.org/docs/advanced-features/middleware
// Example: redirecting a domain to a subdomain
import { NextResponse } from "next/server";
// This function can be marked `async` if using `await` inside
export function middleware(request) {
// Currently there is no main site so we redirect to the subdomain.
const host = request.headers.get("Host");
if (
process.env.NODE_ENV === "production" &&
host.startsWith("mydomain.com")
) {
return NextResponse.redirect(new URL("https://mysubdomain.mydomain.com"));
} else if (
process.env.NODE_ENV === "staging" &&
host.startsWith("staging.mydomain.com")
) {
return NextResponse.redirect(
new URL("https://mysubdomain-staging.mydomain.com")
);
}
}
据我所知有两种方法可以做到这一点:
Next JS 为我们提供了 useRouter 钩子,首先你必须将它导入到你的组件中,然后,要使用 router 对象,你只需要声明它即可。例如:
const 路由器 = useRouter();
console.log(路由器.路径名);
const {路径名} = 路由器; <---- To access the pathname directly.
除此之外,正如@Xairoo之前所说,如果你想使用window对象,你必须检查是否
window !== 'undefined'
以避免错误。发生 window not Define 错误是因为 Next JS 使用 NodeJS 来渲染应用程序,而 Node JS 中未定义 window 对象。
您可以在this链接中找到更详细的解释。
没有哦,上面的答案解决了问题,这是我找到的解决方案:
function return_url(context) {
if (process.env.NODE_ENV === "production") {
// if you are hosting a http website use http instead of https
return `https://${context.req.rawHeaders[1]}`;
} else if (process.env.NODE_ENV !== "production") {
return "http://localhost:3000";
}
}
以及您使用的 getServerSideProps 或 getStaticProps 函数
export async function getServerSideProps(context) {
let url = return_url(context);
const data = await fetch(`${url}/yourEndPoint`).then((res) => res.json());
return {
props: {
data: data,
},
};
}
如果有人正在寻找一种在应用程序目录中执行此操作的简单方法。
import { headers } from "next/headers";
export default function Page() {
const headerList = headers();
const domain = headerList.get("x-forwarded-host") || headerList.get("host") || "beta.popstarz.ai";
console.log(domain);
return (
<main className="flex min-h-screen flex-col items-center justify-between py-3 pb-safe-bottom">
...
</main>
);
}
在 Next.js 中你可以这样做, 在客户端通过useEffect获取window.location.origin, 并将其设置为状态。
工作良好: { “下一个”:“12.1.6”, “反应”:“18.1.0”, }
const Home: NextPage = () => {
const { asPath, query } = useRouter();
const [loading, setLoading] = useState(false);
const [loginCallBackURL, setLoginCallBackURL] = useState("");
useEffect(() => {
setLoginCallBackURL(
`${window.location.origin}/${query.redirect ? query.redirect : "user"}`,
);
}, []);
// if you do something like this, it can't get loginCallBackURL
// const loginCallBackURL = useMemo(() => {
// if (typeof window !== 'undefined') {
// return `${window.location.origin}/${
// query.redirect ? query.redirect : "user"
// }`;
// }
// return asPath;
// }, [asPath, query]);
return (
<div>
<Button
variant="contained"
href={queryString.stringifyUrl({
url: `${publicRuntimeConfig.API_HOST}/auth/google/login`,
query: {
callbackURL: loginCallBackURL,
},
})}
>
Sign in with google
</Button>
</div>
);
};
export default Home;
我们可以这样获取当前的 url:
import { useRouter } from 'next/router';
const router = useRouter();
const origin = typeof window !== 'undefined' && window.location.origin ? window.location.origin : '';
const address_url = origin+router.asPath;