web-dev-qa-db-fra.com

Next.js - Erreur: seules les URL absolues sont prises en charge

J'utilise express comme serveur personnalisé pour next.js. Tout va bien, lorsque je clique sur les produits vers la liste des produits

Étape 1 : je clique sur le lien du produit

enter image description here

Étape 2 : Il affichera les produits dans la base de données.

enter image description here

Cependant, si je rafraîchis le /products page, j'obtiendrai cette erreur

enter image description here

Code serveur (Regardez /products point final)

app.prepare()
.then(() => {
  const server = express()

  // This is the endpoints for products
  server.get('/api/products', (req, res, next) => {
    // Im using Mongoose to return the data from the database
    Product.find({}, (err, products) => {
      res.send(products)
    })
  })

  server.get('*', (req, res) => {
    return handle(req, res)
  })

  server.listen(3000, (err) => {
    if (err) throw err
    console.log('> Ready on http://localhost:3000')
  })
})
.catch((ex) => {
  console.error(ex.stack)
  process.exit(1)
})

Pages - products.js (mise en page simple qui bouclera les données json des produits)

import Layout from '../components/MyLayout.js'
import Link from 'next/link'
import fetch from 'isomorphic-unfetch'

const Products = (props) => (
  <Layout>
    <h1>List of Products</h1>
    <ul>
      { props.products.map((product) => (
        <li key={product._id}>{ product.title }</li>
      ))}
    </ul>
  </Layout>
)

Products.getInitialProps = async function() {

  const res = await fetch('/api/products')
  const data = await res.json()

  console.log(data)
  console.log(`Showed data fetched. Count ${data.length}`)

  return {
    products: data
  }
}

export default Products
8
sinusGob

Comme l'indique l'erreur, vous devrez utiliser une URL absolue pour le fetch que vous créez. Je suppose que cela a quelque chose à voir avec les différents environnements (client et serveur) sur lesquels votre code peut être exécuté. Les URL relatives ne sont tout simplement pas suffisamment explicites et fiables dans ce cas.

Une façon de résoudre ce problème serait simplement de coder en dur l'adresse du serveur dans votre demande fetch, une autre pour configurer un module config qui réagit à votre environnement:

/ config/index.js

const dev = process.env.NODE_ENV !== 'production';

export const server = dev ? 'http://localhost:3000' : 'https://your_deployment.server.com';

products.js

import { server } from '../config';

// ...

Products.getInitialProps = async function() {

  const res = await fetch(`${server}/api/products`)
  const data = await res.json()

  console.log(data)
  console.log(`Showed data fetched. Count ${data.length}`)

  return {
    products: data
  }
}
23
Fabian Schultz

Cas 1. Ce n'est pas une erreur. La récupération isomorphe s'exécute en mode SSR, donc Node.js doit connaître l'URL absolue à extraire, car le serveur principal ne connaît pas les paramètres de votre navigateur.

Cas 2. Un autre scénario consiste à empêcher l'attaque des en-têtes d'empoisonnement de l'hôte http.

ajoutez des clés et des jetons secrets aux liens qui en contiennent:

<a href="http://_SERVER['Host']?token=topsecret">  (Django, Gallery, others)

.... et même en importer directement des scripts:

<script src="http://_SERVER['Host']/misc/jquery.js?v=1.4.4">

Cas 3. Le isomorphic-unfetch c'est la bibliothèque que nous allons utiliser pour récupérer les données. Il s'agit d'une implémentation simple de l'API de récupération de navigateur, mais fonctionne à la fois dans les environnements client et serveur.

En savoir plus à ce sujet:

  1. Récupération isomorphe - Bascule entre la récupération et la récupération des nœuds pour le client et le serveur
  2. Empêche l'attaque des en-têtes de l'hôte http
  3. Récupération des données pour les pages
1
Francis Rodrigues