我有两个项目-- web
和docs
。每一个都是他们自己的Vercel项目,web
项目安装在https://example.com,docs
安装在https://docs.example.com。所有这些都如预期的那样工作。
现在,我希望docs
项目可以在https://example.com/docs上使用。在web
项目中,我在vercel.json
文件中设置了以下重写。
{
"rewrites": [
{
"source": "/docs/:match*",
"destination": "https://docs.example.com/:match*"
},
{ "source": "/(.*)", "destination": "/" }
]
}
这适用于主索引文件,但是所有对应的css和js文件都会导致404。浏览器在下一首查找那些不正确的文件,应该是查看下一首。
我该怎么做呢?
发布于 2022-09-12 06:58:22
rewrite
对redirect
让我们先了解一下这个区别。
重写是只发生在服务器上的事情。服务器将重写已请求的URL并搜索该重写URL的内容。客户对此一无所知。例如,如果/a.html被重写为/b.html,客户端将在两个URL上接收相同的内容。客户端将不知道是否有两次相同的文件,或者是否有一个请求(或两个请求)被重写到其他资源。
另一方面,重定向涉及客户端(即浏览器)。如果服务器需要一个应该被重定向的URL,它将用重写的目标URL回复到客户机/浏览器。然后,客户端将为新URL发送另一个请求,并通过更改导航栏中的地址使其对最终用户可见。如果/a.html被重定向到/b.html,则在请求a.html时,客户端将不会收到b.html的实际内容,但是浏览器将更新地址到b.html并发送新请求。
在你的案例中重写有什么问题?
HTML包含对使用绝对路径的其他资源的引用,例如:
<script src="/_next/static/..."></script>
如果这个文件应该被用作docs.example.com
和example.com/docs
(例如使用重写),那么实际的HTML不会改变。因此,浏览器将尝试分别访问docs.example.com/_next/static/...
或example.com/_next/static/...
。这适用于第一种情况(docs.example.com
),但不适用于第二种情况。你已经注意到了。
您可以将next的basePath
更改为/docs
。然后HTML将包含<script src="/docs/_next/...">
。这将分别使浏览器请求docs.example.com/docs/_next/...
或example.com/docs/_next/...
。这将适用于第二种情况,但不适用于第一种情况。你可以用更多的重写规则来治愈第一个病例,但我建议一个吻解决方案。
这次又是什么?
正如评论中提到的,将完全相同的内容放在两个不同的地址并不是好的做法。你可以看到,这也导致了随后的困难。(更别提搜索引擎对重复内容的处罚了。)
一个好的解决方案是决定在哪里存储内容。这应该是docs.example.com
或example.com/docs
,而不是两者兼而有之。
使用docs.example.com将example.com/docs/转发给docs.example.com
我建议(并假设在本节中)采取docs.example.com
有一个明确的关注点分离。
所以在Vercel,你会建立两个项目。一个用于“主”下一个实例,另一个用于"docs“下一个实例。(两者都可以来自同一个回购,这并不重要。)
然后将域分配给两个项目,例如,www.example.com
分配给“主”项目,docs.example.com
分配给"docs“项目。example.com
和docs.example.com
现在应该都在工作。example.com/docs/
应该会产生404错误。
然后添加重定向(而不是重写!)为您的“主”项目添加如下所示的vercel.json
:
{
"redirects": [
{ "source": "/docs/:path*", "destination": "https://docs.example.com/:path*" }
]
}
现在,如果在浏览器中输入example.com/docs/foo
,则应该重定向到docs.example.com/foo
,并且页面应该正确加载。
仅使用example.com/docs/
如果您决定只在example.com/docs/
上使用docs内容,则解决方案如下:
basePath: '/docs'
添加到docs下一个项目的next.config.js
中。不要向此vercel项目添加域。vercel.json
,并进行如下重写:{
"rewrites": [
{ "source": "/docs", "destination": "https://$domain-of-docs-project.vercel.app/docs" },
{ "source": "/docs/:path*", "destination": "https://$domain-of-docs-project.vercel.app/docs/:path*" }
]
}
请评论,如果你有额外的问题或这不能解决问题。
发布于 2022-09-12 01:09:13
我认为您可以这样使用vercel.json:
{
"rewrites": [
{
"source": "/:path*",
"has": [
{
"type": "host",
"value": "docs.example.com"
}
],
"destination": "/docs/:path*"
}
]
}
发布于 2022-09-13 18:14:31
接下来给出了一个具体的例子。
您的"web“项目应该处理重写,如这里所示。next.config.js:
const { DOCS_URL } = process.env //this should be the vercel URL NOT docs.example.com
/** @type {import('next').NextConfig} */
module.exports = {
async rewrites() {
return [
{
source: '/:path*',
destination: `/:path*`,
},
{
source: '/docs',
destination: `${DOCS_URL}/docs`,
},
{
source: '/blog/:path*',
destination: `${BLOG_URL}/docs/:path*`,
},
]
},
}
您的"docs“应用程序需要设置一个基本路径,如这里所示。next.config.js:
module.exports = {
basePath: '/docs',
}
然后,为了确保docs.example.com不再为文档提供服务,我只需删除DNS记录即可。相反,您将只有一个vercel URL,您将在重写中使用"web“。无需从docs.example.com指向该服务器。
https://stackoverflow.com/questions/73607646
复制相似问题