我在 render.com 上部署了我的项目,我的应用程序在此链接中上线 https://react-router-events-j6yu.onrender.com/
但是,当我访问带有
/events
的 URL 时,UI 消失,页面显示如下:
// 20240523233320
// https://react-router-events-j6yu.onrender.com/events/55b79b2e-902f-44b1-b292-08ab669b76c6
{
"event": {
"title": "Test again...",
"image": "https://www.meydanfz.ae/wp-content/uploads/2021/10/Events-1024x576.png",
"date": "2024-06-08",
"description": "Test",
"id": "55b79b2e-902f-44b1-b292-08ab669b76c6"
}
}
它呈现 JSON 数据而不是 HTML。
我联系了渲染器的支持人员,他们说这可能是应用程序问题,而不是特定于渲染器的问题。
事实上,我在渲染时创建了一个“Web 服务”来同时托管我的后端和前端应用程序。
我认为渲染上的配置是正确的。
所以,我在这里向您展示一些我的代码,以便您有希望检测到错误。
项目的结构是随后的:
/my-project
/backend
app.js
events.json
/data
events.js
/routes
events.js
/util
error.js
validation.js
/frontend
/build
index.html
// other build files
src
// my React source files
const express = require('express');
const bodyParser = require('body-parser');
const path = require('path');
const eventRoutes = require('./routes/events');
const app = express();
const PORT = process.env.PORT || 8080;
app.use(bodyParser.json());
app.use((req, res, next) => {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', 'GET,POST,PATCH,DELETE');
res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
next();
});
// Serve static files from the React app
app.use(express.static(path.join(__dirname, '../frontend/build')));
// API routes
app.use('/events', eventRoutes);
// The "catchall" handler: for any request that doesn't match one above, send back React's index.html file.
app.get('*', (req, res) => {
console.log('Serving index.html for request:', req.url);
res.sendFile(path.join(__dirname, '../frontend/build', 'index.html'));
});
// Error handling middleware
app.use((error, req, res, next) => {
const status = error.status || 500;
const message = error.message || 'Something went wrong.';
res.status(status).json({ message: message });
});
// Start the server
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});
const fs = require('node:fs/promises');
const path = require('path');
const { v4: generateId } = require('uuid');
const { NotFoundError } = require('../util/errors');
// Utilisation de path.resolve pour garantir le bon chemin d'accès
const dataFilePath = path.resolve(__dirname, '../events.json');
async function readData() {
try {
console.log('Reading data from:', dataFilePath); // Ajout de log pour vérifier le chemin
const data = await fs.readFile(dataFilePath, 'utf8');
return JSON.parse(data);
} catch (error) {
console.error('Failed to read data:', error);
throw new Error('Could not read events data.');
}
}
async function writeData(data) {
try {
console.log('Writing data to:', dataFilePath); // Ajout de log pour vérifier le chemin
await fs.writeFile(dataFilePath, JSON.stringify(data));
} catch (error) {
console.error('Failed to write data:', error);
throw new Error('Could not write events data.');
}
}
async function getAll() {
const storedData = await readData();
if (!storedData.events) {
throw new NotFoundError('Could not find any events.');
}
return storedData.events;
}
async function get(id) {
const storedData = await readData();
if (!storedData.events || storedData.events.length === 0) {
throw new NotFoundError('Could not find any events.');
}
const event = storedData.events.find(ev => ev.id === id);
if (!event) {
throw new NotFoundError('Could not find event for id ' + id);
}
return event;
}
async function add(data) {
const storedData = await readData();
storedData.events.unshift({ ...data, id: generateId() });
await writeData(storedData);
}
async function replace(id, data) {
const storedData = await readData();
if (!storedData.events || storedData.events.length === 0) {
throw new NotFoundError('Could not find any events.');
}
const index = storedData.events.findIndex(ev => ev.id === id);
if (index < 0) {
throw new NotFoundError('Could not find event for id ' + id);
}
storedData.events[index] = { ...data, id };
await writeData(storedData);
}
async function remove(id) {
const storedData = await readData();
const updatedData = storedData.events.filter(ev => ev.id !== id);
await writeData({ events: updatedData });
}
exports.getAll = getAll;
exports.get = get;
exports.add = add;
exports.replace = replace;
exports.remove = remove;
如果需要,我可以为您提供更多详细信息。
这绝对是应用程序问题,而不是渲染上的不正确配置。
事实上,这里发生的是客户端路由和服务器路径的混淆。
当你浏览网站并点击“事件”导航链接时,这并不是真正从服务器加载
/events
- 这是 React Router 更改地址,使其看起来像是该路径,然后你的 JS 正在获取 /events
来自服务器。
刷新时,您是在告诉浏览器从
/events
加载 - 这是您加载 JSON 的路径。
要解决此问题,您应该将服务器路径
/events
(https://github.com/sofiane-abou-abderrahim/react-router-events/blob/test/backend/app.js#L21) 更新为像 /data
这样的东西,然后更新你的 JS 以从 /data
获取。 (https://github.com/sofiane-abou-abderrahim/react-router-events/blob/test/frontend/src/pages/Events.js#L21)
这样,单击“事件”,会将浏览器更改为
/events
并从/data
加载数据,刷新意味着您的“*捕获服务器中的所有路径”将重定向并由React Router处理它。