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
Étape 2 : Il affichera les produits dans la base de données.
Cependant, si je rafraîchis le /products
page, j'obtiendrai cette erreur
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
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
}
}
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.