英文:
Getting 404 Not Found error when refreshing dynamic page in DirectAdmin deployment
问题
I've translated the code-related parts of your content as requested:
我在尝试刷新我的Next.js应用程序上的动态页面时遇到了“404 Not Found”错误,该应用程序部署在DirectAdmin上。仅当我尝试刷新页面时才会出现错误,但从不同路由导航到页面时一切正常。
这是我的设置详细信息:
- 我正在使用Next.js进行应用程序开发。
- 我有一个动态页面,路由类似于/products/[id],其中[id]代表每个产品的唯一标识符。
- 我已将我的应用程序部署到DirectAdmin上,并且正在使用默认的路由配置。
当我进入动态页面,比如/products/123,一切正常。但是,如果我刷新页面或直接访问URL/products/123,我会收到以下错误消息:
> 未找到
> 未找到请求的URL。
>
> 此外,在尝试使用ErrorDocument处理请求时遇到了404未找到错误。
我怀疑DirectAdmin的路由配置可能存在问题,但我不确定如何解决它。我已检查了我的Next.js页面和路由设置,似乎一切正常。
我在其他类型的服务器上进行了测试,一切都正常,但我认为DirectAdmin存在问题!
这是我的代码:
pages/index.jsx
import Link from 'next/link';
import { useEffect, useState } from 'react';
export default function HomePage() {
const [todos, setTodos] = useState([]);
useEffect(() => {
async function fetchData() {
const res = await fetch('https://jsonplaceholder.typicode.com/todos?_sort=id&_order=ascs&_limit=5');
const data = await res.json();
setTodos(data);
}
fetchData();
}, []);
return (
{todos && (
<div>
<h1>Todos</h1>
{
todos.map(todo => (
<Link
href={`/todo/${todo.id}`}
className="block p-2"
>
{todo.title}
</Link>
))}
</div>
)}
)
}
pages/todo/[slug].jsx
import { useRouter } from 'next/router';
import { useState, useEffect } from 'react';
export default function Todo() {
const router = useRouter();
const { id } = router.query;
const [todo, setTodo] = useState(null);
useEffect(() => {
async function fetchTodo() {
const res = await fetch(`https://jsonplaceholder.typicode.com/todos/${id}`);
const data = await res.json();
setTodo(data);
}
if (id) {
fetchTodo();
}
}, [id]);
if (!todo) {
return <div>Loading...</div>;
}
return (
<div>
<p>{todo.id}</p>
<h1>{todo.title}</h1>
</div>
);
}
next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
output: 'export',
trailingSlash: true,
}
module.exports = nextConfig;
英文:
I'm encountering a "404 Not Found" error when trying to refresh a dynamic page in my Next.js application deployed on DirectAdmin. The error occurs only when I attempt to refresh the page, but navigating to it from a different route works fine.
Here are the details of my setup:
- I'm using Next.js for my application.
- I have a dynamic page with a route like /products/[id], where [id] represents the unique identifier for each product.
- I've deployed my application on DirectAdmin, and I'm using the default configuration for routing.
When I land on a dynamic page, let's say /products/123, everything works as expected. However, if I refresh the page or directly access the URL /products/123, I receive the following error:
> Not Found
> The requested URL was not found on this server.
>
> Additionally, a 404 Not Found error was encountered while trying to use an ErrorDocument to handle the request.
I suspect there might be an issue with the routing configuration in DirectAdmin, but I'm not sure how to resolve it. I've checked my Next.js pages and routing setup, and everything seems to be in order.
I tested it on other types of servers and it worked well, but I think there is a problem with Directadmin!
Here's my code:
pages/index.jsx
import Link from 'next/link'
import { useEffect, useState } from 'react'
export default function HomePage() {
const [todos, setTodos] = useState([]);
useEffect(() => {
async function fetchData() {
const res = await fetch('https://jsonplaceholder.typicode.com/todos?_sort=id&_order=ascs&_limit=5');
const data = await res.json();
setTodos(data);
}
fetchData();
}, []);
return (
{todos && (
<div>
<h1>Todos</h1>
{
todos.map(todo => (
<Link
href={`/todo/${todo.id}`}
className="block p-2"
>
{todo.title}
</Link>
))}
</div>
)}
)
}
pages/todo/[slug].jsx
import { useRouter } from 'next/router';
import { useState, useEffect } from 'react';
export default function Todo() {
const router = useRouter();
const { id } = router.query;
const [todo, setTodo] = useState(null);
useEffect(() => {
async function fetchTodo() {
const res = await fetch(`https://jsonplaceholder.typicode.com/todos/${id}`);
const data = await res.json();
setTodo(data);
}
if (id) {
fetchTodo();
}
}, [id]);
if (!todo) {
return <div>Loading...</div>;
}
return (
<div>
<p>{todo.id}</p>
<h1>{todo.title}</h1>
</div>
);
}
next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
output: 'export',
trailingSlash: true,
}
module.exports = nextConfig
答案1
得分: 1
在导航到一个路由时,你可能会通过Link
组件传递一些参数,像这样:
<Link
href={{
pathname: '/about',
query: { name: 'test' },
}}
>
About
</Link>
但是在刷新页面时,Next.js 可能没有获取到路径数据。请检查你的next.config.js
中的重写规则:
const nextConfig = {
async rewrites() {
return [
{
source: "/products/:id",
destination: "/products/:id",
locale: false
},
]
}
}
module.exports = nextConfig;
希望这对你有帮助。
英文:
While navigating to a route you're probably passing some parameters through Link
component like this:
<Link
href={{
pathname: '/about',
query: { name: 'test' },
}}
>
About
</Link>
But while refreshing the page nextjs is probably not getting the path data. Check your rewrite rules in next.config.js
const nextConfig = {
async rewrites() {
return [
{
source: "/products/:id",
destination: "/products/:id",
locale: false
},
]}
}
module.exports = nextConfig;
答案2
得分: 1
由于下一次导出的原因。
Next导出构建了静态HTML文件。如果您查看输出文件夹,您可能会看到类似以下内容。
这是浏览器所看到的。因此,由于静态输出中没有匹配/todo/1.html
的HTML文件,它会产生404错误。
解决方案
配置重写
当服务器收到对/todo/1
的请求时,您希望为用户提供/todo/[slug]/index.html
。
重写通常很容易设置
不要使用next export
如果关闭next export,它将按您的预期工作。
英文:
The reason for this is because of next export.
Next export builds static HTML files. If you look at your output folder you probably see something like this.
This is what the browser sees. So since there is no HTML file is in the static output that matches /todo/1.html it produces a 404.
Solutions
Configure a rewrite
When the server gets a request for /todo/1 you want to serve the user /todo/[slug]/index.html.
Rewrite are normal pretty easy to set up
Don't use next export
If you turn off next export it will work as you expect
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论