Next.js: Пользовательский маршрут `post /` id` мигает 404 перед окончательной визуализацией страницы.

Созданный на 22 авг. 2017  ·  47Комментарии  ·  Источник: vercel/next.js

В настоящее время у меня возникла проблема с моими маршрутами post/:id где затем мигает страница 404 перед успешной визуализацией моего компонента. Сначала я подумал, что это проблема, связанная с сокращением, поскольку мои страницы post/id проверяют состояние приложения на filter какой бы компонент не отображался, используя мелкую маршрутизацию.

Обсудив это в канале Slack, я добавил еще один вызов API, который будет извлекать каждое сообщение в блоге, но быстро обнаружил, что все еще сталкиваюсь с той же проблемой. Я знаю, что это произошло по крайней мере с одним другим разработчиком, поэтому мне интересно, может ли кто-нибудь указать мне в правильном направлении? Я пытаюсь завершить это личное портфолио, которое я построил следующим.

Ниже вы можете точно увидеть, что происходит. Все выглядит как A1, за исключением 404, который мигает при рендеринге определенного поста.

next.js blog post err

Польза, которую я получил, огромна, однако были некоторые незначительные проблемы, подобные этой, которые меня немного озадачили 🤔. В любом случае, дайте мне знать, могу ли я предоставить дополнительную информацию. Спасибо 😄

Самый полезный комментарий

Итак, чтобы ответить на этот вопрос раз и навсегда:

href => путь внутри каталога pages + строка запроса
as => отображается в строке URL браузера

Пример:

У вас есть URL с названием /products/:id

  1. Вы создали pages/product.js
export default class extends React.Component {
  static async getInitialProps({query}) {
    console.log('SLUG', query.slug)
    return {}
  }
  render() {
    return <h1>The product page</h1>
  }
}
  1. Вы добавляете маршрут на экспресс или любой другой сервер, это только для SSR. Это будет перенаправлять url /products/:id на pages/product.js и предоставлять id как часть query в getInitialProps:
server.get("/products/:slug", (req, res) => {
  return app.render(req, res, "/product", { slug: req.params.slug })
})
  1. Для маршрутизации на стороне клиента вы используете next/link следующим образом:
<Link href="/product?slug=something" as="/products/something"> 

Причина, по которой вы должны явно указать href и as заключается в том, что Next.js не знает никаких других страниц на стороне клиента. Мы не отправляем манифест всех страниц на клиентскую сторону, и последующие маршруты загружаются лениво, что является масштабируемым.

Существует пакет сообщества, который абстрагируется, предоставляя href и as , отправляя заранее определенный манифест всех маршрутов, обратите внимание, что мы не рекомендуем отправлять полный манифест всех возможных маршрутов, поскольку этого не происходит. более масштабируемый

https://github.com/fridays/next-routes

Также обратите внимание, что рендеринг 404 больше не является поведением Next.js. Вместо этого мы перезагружаем страницу для функции Зоны.

Все 47 Комментарий

Та же проблема +1

Как вы визуализируете компонент Link для этого URL-адреса? Вы используете <Link href="/post/1"> или <Link href="/post?id=1" as="/post/1"> ?

В настоящее время я использую <Link prefetch href={ /blog/${x.id} } /> . Я пробовал <Link prefetch href={ /blog/${x.id} } as={ /blog/${x.id} } /> в прошлом и просто подключил его снова. По-прежнему возникает та же проблема.

Ваши реквизиты href и as не должны быть одинаковыми, href - это реальный URL-адрес, если у вас есть pages/blog.js и вы получаете идентификатор в качестве запроса, тогда href должно быть /blog?id=${x.id} а as - ваш симпатичный URL-адрес в данном случае /blog/${x.id} .

@sergiodxa Я просто вставил этот код на место.

<Link href={`/blog?id=${x.id}`} as={`blog/${x.id}`}>
    <a>Read Post</a>
 </Link>

Теперь он повторно отображает страницу /blog при каждом щелчке, добавляя id к URL-адресу.

url error gif

@tgrecojs Надеюсь, этот фрагмент кода поможет

    const href = `/journal?home=${this.state.article.path[0]}&articlePath=${this.state.article.path[1]}&file=${this.state.article.path[2]}`
    const as = `/journal/${this.state.article.path[0]}/${this.state.article.path[1]}/${this.state.article.path[2]}`

Будет отображаться как https://www.someURL.com/journal/articlePath/morePath/evenMorePath

Я понимаю, как работает путь @ugiacoman , это не моя проблема. Если вы видите в моем первоначальном отчете, я успешно перехожу к каждому сообщению в блоге, однако проблема заключается в странной ошибке 404 .

@tgrecojs Я сделал пример https://github.com/sergiodxa/next-custom-query (развернут: https://next-custom-query.now.sh/blog), там вы можете увидеть, как использовать настраиваемые URL-адреса без перезагрузки и 404 с использованием компонента next/link как описано выше.

@sergiodxa Я ценю это! Я только что проверил это и добавил несколько асинхронных вызовов в API Google Blogger, что я сейчас проверяю. Ниже вы можете увидеть, как он перемещается по маршруту, но данные загружаются неправильно.

Удален gif

Теперь этот выпуск представляет собой несколько иное воспроизведение этой проблемы, чем то, что показано в моем первом комментарии. Когда я впервые столкнулся с этой проблемой, я подумал, что это потому, что я использую redux и что состояние приложения не переносит страницы post/id . Это привело меня к интеграции нового вызова API для каждого сообщения, точно так же, как я интегрировал в созданное вами приложение, однако я все же обнаружил, что у меня такая же проблема.

У меня возникли проблемы с разветвлением вашего репо 😬, поэтому вы можете найти мой код здесь -> https://github.com/tgrecojs/next-custom-query-async . Дайте мне знать, что вы думаете! 😄

Похоже, вы получаете 400, при разветвлении вашего проекта я получаю ту же ошибку с сообщением об ошибке usageLimits. Вероятно, поэтому вы получаете эту ошибку.

Ok. Я немного займусь этим завтра, но хочу отметить, что видео, которое я опубликовал при открытии проблемы, не делает запрос API на маршруте /blog/:id . Вместо этого он фильтрует сообщения из моего хранилища redux, которые собираются при переходе маршрута /blog так что это не могло быть причиной, по которой я пришел к этой проблеме. Я реализовал только второй вызов API (сделанный внутри blog/:id ), так как я думал, что это как-то связано с моим redux-store, но обнаружил, что получаю ту же ошибку, но это не текущая реализация в моем коде.

Как только я понял, что это вызывает ту же ошибку, я снова переключился на использование только одного вызова API (внутри /blog ), а затем отфильтровал нужную запись в блоге по идентификатору.

@sergiodxa Я могу подтвердить, что это не ограничения на использование. Вы увидите, что id не всегда правильно передается в маршрут /blog/:id ... Я добавил ошибку 400 которую я получаю. Вы увидите, что id не определено, и (в этом случае), похоже, именно поэтому я получаю сообщение об ошибке.

Я добавил еще одно видео ниже. Есть мысли о том, почему он может так себя вести? Я не менял теги <Link /> внутри этого репозитория, но проблема не устранена 😬.

next-custom-query err

Опять же, я хочу указать, что на видео выше показано, как я воспроизводю ошибку в примере репозитория, который вы создали - https://github.com/sergiodxa/next-custom-query .

Я также получаю мигание 404 без каких-либо пользовательских маршрутов. Просто файл с именем orders.js в pages/ с таким кодом:

import { Component } from 'react';

class Orders extends Component {
  render() {
    return (
      <div>
        <h2>My Orders</h2>
      </div>
    )
  }
}

export default Orders;

Вроде бы довольно критическая проблема 😅

Я попытался воспроизвести это, потому что косая черта в конце URL-адреса, если вы перейдете к /orders вы не увидите 404, но если вы перейдете к /orders/ вы увидите, что 404 мигает перед содержимым, это происходит как в режиме разработки, так и в режиме производства.

Ах, это известная проблема. https://github.com/zeit/next.js/issues/1189

Моя проблема возникла не из-за косой черты в конце, так что должно быть что-то еще, верно?

Я внес некоторые изменения в свой код и развернул 2 разные версии, в одной из которых используется prefetch а в другой нет. Хочу отметить, что ни одно приложение теперь не может успешно загрузить маршрут post/:id .

С предварительной выборкой - https://tgrecojs-hltqztsjpx.now.sh/

Один заметил, что когда я использую prefetch в ссылке, теперь он выдает Page Does Not Exist Error при рендеринге ссылок для каждого сообщения в блоге. Вы можете увидеть снимок экрана моей консоли ниже.

screen shot 2017-08-26 at 1 06 25 pm

Без предварительной выборки - https://tgrecojs-qzpspdjrin.now.sh/

Когда я не использую предварительную выборку, показанная выше ошибка больше не существует, но она не отображает приложение. Когда я впервые опубликовал эту проблему, мой компонент инициализировал мой блог для каждого компонента post/:id . С тех пор я удалил это, так как теперь отдельные сообщения никогда не отображаются.

Сообщите мне, могу ли я предоставить дополнительную информацию, которая поможет диагностировать эту проблему. 🤔

@tgrecojs У меня почти такая же проблема. prefetch не решил мою проблему.

Я получаю следующее поведение:

  • Пользователь нажимает на ссылку
  • Появляется ошибка 404
  • Страница перезагружается (??)
  • После перезагрузки отображается правильная страница

Надеюсь, это поможет решить проблему!

Дополнительная информация: Node v6.10.3 , Chrome Version 60.0.3112.90

РЕДАКТИРОВАТЬ: развернуло приложение, чтобы вы, ребята, могли его протестировать https://datahub.now.sh/ , это ссылка / @ [username], которая имеет такое поведение

@ Theo - href в следующей / ссылке - user?id=1 , можете ли вы вместо этого попробовать /user?id=1 ? Я думаю, что ошибка 404 вызвана тем, что Next.js пытается добраться до /current/path/user?id=1 вместо /user?id=1 , но при перезагрузке страницы он работает нормально из-за рендеринга сервера.

@sergiodxa, который это сделал. Спасибо!

@tgrecojs У меня было такое же поведение при https://medium.com/the-tech-bench/next-js-environment-variables-d2f6ea1a1dca.

@andreaskeller хммм хорошо, я проверю. спасибо вам это !!! В настоящее время я использую свои переменные .env ТОЛЬКО, когда приложение рендерится на сервере. У меня есть компонент более высокого порядка, который использует dotenv для проверки CSR или SSR, если это SSR, я отправляю функцию, необходимую для регистрации сообщений в блоге.

да, мои переменные уже работают нормально. Я визуализирую этот мой /blog маршрут с помощью HOC, который получает мой BLOGGER_API_KEY поэтому он работает в этих примерах .... мои дочерние страницы /post/:id s не используют никаких переменные env.

собираюсь покопаться еще немного, надеюсь, я смогу добраться до сути!

Кажется, что большинство проблем здесь исправлено. Я тоже поработаю над этой проблемой https://github.com/zeit/next.js/issues/1189

Я закрываю это сейчас. Но если нам нужно что-то сделать по сути, дайте мне знать.

@sergiodxa, согласно нашему

Это не исправлено.

У меня такая же проблема, но без пользовательских маршрутов. У меня есть /pages/pipeline.tsx и URL-адрес / pipeline работает нормально, в то время как / pipeline / мигает 404, а затем пытается загрузить мою страницу без вызова "getInitialProps" (так как на сервере это было 404!).

@ ex3ndr Не уверен, что это решит проблему, но у меня была аналогичная проблема, и это вылечило ее.
https://github.com/zeit/next.js#dispting -file-system-routing

Скорее всего, следующая попытка отключить файловую систему до того, как будет достигнут ваш пользовательский маршрут.

@moaxaca Я решил так же, так как мне нужно было иметь собственную настраиваемую маршрутизацию - я просто отключил следующий.

Я тоже вижу эту проблему. Решение @moaxaca не сработало для меня. Что нужно сделать, так это использовать любой компонент Link , но вместо этого выбрать метод pushRoute следующего маршрута.

Базовый пример:

import { connect } from 'react-redux'
import { Router } from '../routes'

// ----

export default class Link extends React.Component {

  handleClick(evt, url) {
    evt.preventDefault()    
    Router.pushRoute(url)
  }

  render() {
    const { url, title } = this.props

    return (
      <a href={ url} onClick={ (evt) => this.handleClick(evt, url) }>{title}</a>
    )
  }

}

Кажется, это выяснилось, и я не вижу мигания ошибки. Но это кажется немного заторможенным.

сохранить проблему

У меня была такая же проблема раньше, и я смог ее решить. Я использую настроенный экспресс-сервер. Я выяснил, что причина, по которой страница 404 мигает перед загрузкой на нужную страницу, заключается в том, что название моей страницы не соответствует имени моего компонента.

Когда у меня есть этот код, мигает 404:

server.get('/search', (req, res) => {
    const actualPage = '/search_results'
    const queryParams = { filters: req.query }
    app.render(req, res, actualPage, queryParams)
  })

Обратите внимание, что значения /search и моего actualPage различны.

Мигание 404 исчезает, когда я переименовываю свой компонент и значения actualPage чтобы они совпадали с заголовком моей страницы, который равен search . См. Рабочий код ниже:

server.get('/search', (req, res) => {
    const actualPage = '/search'
    const queryParams = { filters: req.query }
    app.render(req, res, actualPage, queryParams)
  })

Теперь оба используют /search .

Извините за моих английских ребят.

может быть хорошей идеей проверить ваше свойство next.config.js useFileSystemPublicRoutes . Если это false, это означает, что вы должны сами определить все обработчики маршрутов в server.js.

Это исправляет мигающую ошибку 404 для меня:

Ссылка

<Link href="/somepage?id=value" as="/somepage/value">

Сторона сервера

server.get("/somepage/:id", (req, res) => {
  return app.render(req, res, "/maps", { id: req.params.id })
})

Параметр доступа на странице

const { id } = this.props.url.query

Итак, чтобы ответить на этот вопрос раз и навсегда:

href => путь внутри каталога pages + строка запроса
as => отображается в строке URL браузера

Пример:

У вас есть URL с названием /products/:id

  1. Вы создали pages/product.js
export default class extends React.Component {
  static async getInitialProps({query}) {
    console.log('SLUG', query.slug)
    return {}
  }
  render() {
    return <h1>The product page</h1>
  }
}
  1. Вы добавляете маршрут на экспресс или любой другой сервер, это только для SSR. Это будет перенаправлять url /products/:id на pages/product.js и предоставлять id как часть query в getInitialProps:
server.get("/products/:slug", (req, res) => {
  return app.render(req, res, "/product", { slug: req.params.slug })
})
  1. Для маршрутизации на стороне клиента вы используете next/link следующим образом:
<Link href="/product?slug=something" as="/products/something"> 

Причина, по которой вы должны явно указать href и as заключается в том, что Next.js не знает никаких других страниц на стороне клиента. Мы не отправляем манифест всех страниц на клиентскую сторону, и последующие маршруты загружаются лениво, что является масштабируемым.

Существует пакет сообщества, который абстрагируется, предоставляя href и as , отправляя заранее определенный манифест всех маршрутов, обратите внимание, что мы не рекомендуем отправлять полный манифест всех возможных маршрутов, поскольку этого не происходит. более масштабируемый

https://github.com/fridays/next-routes

Также обратите внимание, что рендеринг 404 больше не является поведением Next.js. Вместо этого мы перезагружаем страницу для функции Зоны.

Спасибо, Тим, совершенно ясное объяснение!

@timneutkens
Если ссылка href и as. Я передаю другое значение. Как я могу получить значение href и значение as .
Тестирую демку. Я думаю, что req.params.slug будет значением as . Тогда как я могу получить значение href .

@timneutkens Ты меня спас, я не знаю, сколько часов мучительных поисков моей проблемы: D

Как вы визуализируете компонент Link для этого URL-адреса? Вы используете <Link href="/post/1"> или <Link href="/post?id=1" as="/post/1"> ?

Вы должны поместить это в документ. :радость:

@sergiodxa

Итак, чтобы ответить на этот вопрос раз и навсегда:

href => путь внутри каталога pages + строка запроса
as => отображается в строке URL браузера

Пример:

У вас есть URL с названием /products/:id

  1. Вы создали pages/product.js
export default class extends React.Component {
  static async getInitialProps({query}) {
    console.log('SLUG', query.slug)
    return {}
  }
  render() {
    return <h1>The product page</h1>
  }
}
  1. Вы добавляете маршрут к экспрессу или любому другому серверу, это _только_ для SSR. Это будет перенаправлять url /products/:id на pages/product.js и предоставлять id как часть query в getInitialProps:
server.get("/products/:slug", (req, res) => {
  return app.render(req, res, "/product", { slug: req.params.slug })
})
  1. Для маршрутизации на стороне клиента вы используете next/link следующим образом:
<Link href="/product?slug=something" as="/products/something"> 

Причина, по которой вы должны явно указать href и as заключается в том, что Next.js не знает никаких других страниц на стороне клиента. Мы не отправляем манифест всех страниц на клиентскую сторону, и последующие маршруты загружаются лениво, что является масштабируемым.

Существует пакет сообщества, который абстрагируется, предоставляя href и as , отправляя заранее определенный манифест всех маршрутов, обратите внимание, что мы не рекомендуем отправлять полный манифест всех возможных маршрутов, поскольку этого не происходит. более масштабируемый

https://github.com/fridays/next-routes

Также обратите внимание, что рендеринг 404 больше не является поведением Next.js. Вместо этого мы перезагружаем страницу для функции Зоны.

что я могу сделать, если у меня есть только массив заголовков списка, например:
[ home: '/home', about:'/about', post: 'post/:post_id?' ] .
Далее я получаю только значение as's , но как насчет href ? Спасибо

Что делать, если вы используете router.push() вместо <Link> как вы можете достичь тех же результатов?

@justinmchase У меня была такая же проблема. Проверьте документацию Next Router, если вы еще этого не сделали.

Вы можете использовать его как Router.push(url, as, options) :

Router.push('/post/[pid]', '/post/abc')

@timneutkens Я хотел бы разместить свое приложение next.js на ZEIT.now, но у него нет возможности запустить экспресс-сервер. Я теряю свои красивые URL-адреса и могу делать только param=value&param=value или есть другой способ? Пример, опубликованный Серхио, не выглядит многообещающим.

Я пробовал динамические маршруты, но теперь мое одностраничное приложение не работает и есть такие ссылки, как:

<Link href={`/integration?slug=${slug}`} as={`/integration/${slug}`}>

теперь вызывает полную перезагрузку страницы, потому что http: // localhost : 8080 / _next / static / development / pages / integration.js возвращает 404 not found.

@timneutkens Я хотел бы разместить свое приложение next.js на ZEIT.now, но у него нет возможности запустить экспресс-сервер. Я теряю свои красивые URL-адреса и могу делать только param=value&param=value или есть другой способ? Пример, опубликованный Серхио, не выглядит многообещающим.

Вам не нужен собственный сервер для динамических маршрутов, см. Https://nextjs.org/docs/routing/dynamic-routes

@timneutkens Спасибо за ваш быстрый ответ, я пробовал динамические маршруты, но сломает одностраничное приложение (см. обновление). Запускается локально с next в моем скрипте package.json в режиме разработки.

Решил это, имея pages/integration/index.js с кодом и pages/integration/[slug].js с:

import ProductDetailPage from './index'
export default ProductDetailPage

Правильный способ сделать то, что вы изложили, - создать pages/integration/[slug].js

И ссылку на него таким образом:

<Link href={`/integration/[slug]`} as={`/integration/${slug}`}>

Привет, могу я спросить, почему, когда я звоню этому

Router.push( '/about?id=1234','/about')

идентификатор не может быть получен, а страница, которую я использую, - это [... index] .js, которая является многодинамической страницей для захвата всей страницы, но если я перенаправляю на другую страницу, которая не является динамической, она может работать правильно, например, car.js нажмите на vehicle.js ..
Есть ли лучший способ, при котором я могу нажать на мою страницу динамического захвата всей страницы, а затем замаскировать идентификатор и все еще иметь возможность его получить ...?

Была ли эта страница полезной?
0 / 5 - 0 рейтинги