我正在建立一个电子商务,由于某种原因,我希望它成为SPA。既然我快完成了,就没有回头路了。
首先,我使用history.pushState和popstate事件建立了一个历史记录。来回导航也很好,而且速度很快。
问题是,如果用户导航到CPU部分,pushState将按如下所示进行链接:localhost:2000 / pages / cpu,每个页面都有自己的“链接”。但是,如果用户导航到localhost:2000 / pages / cpu,则快速返回将不会出错。显而易见。
我真的很困,只有我能提出以下几点:
const express = require('express');
const fs = require('fs');
const socket = require('socket.io');
const app = express();
const server = app.listen(2000);
const io = socket(server);
const paths = [
{
path: '/pages/games',
msg: 'gamesRes',
}, {
path: '/pages/cpu',
msg: 'cpuRes',
}, {
path: '/pages/play_station',
msg: 'playStationRes',
}
];
app.use('/client', express.static(__dirname + '/client'));
app.set('socketio', io);
app.get('/', (req, res) => res.sendFile(__dirname + '/client/index.html'));
paths.forEach(function(prop) {
app.get(prop.path, function(req, res) {
res.sendFile(__dirname + '/client/index.html');
const io = req.app.get('socketio');
const socketId = [];
io.on('connection', function(socket) {
socketId.push(socket.id);
if(socketId[0] === socket.id) {
io.removeAllListeners('connection');
}
// prop file has been moved to the client, so this does nothing ATM
socket.emit(prop.msg, prop.file);
});
});
});
io.on('connection', function(socket) {
// login, register, stuff.....
});
因此,接下来,客户端将侦听与正确URL相匹配的正确套接字,并呈现页面。但是,当他着陆时,套接字连接被关闭,并且登录/注册和其他内容不可用。这种方法好吗?如果我将登录,注册和其他套接字事件放在app.get的IO连接事件中可以吗? 有什么框架可以解决这个问题,因为我不认为表达是为这位工作之王准备的。
谢谢!
答案 0 :(得分:0)
好吧,我已经玩了几个星期了,我设法让它开始工作。
首先,创建一个包含服务器上所有URL的数组:
const paths = [
{
path: '/pages/games',
page: 'games',
}, {
path: '/pages/cpu',
page: 'cpu',
}, {
path: '/pages/playStation',
page: 'playStation',
}
];
接下来一些表达功能:
app.use('/client', express.static(__dirname + '/client'));
app.set('socketio', io); // so we can use it in app.get I guess
app.get('/', (req, res) => res.sendFile(__dirname + '/client/index.html'));
到目前为止,问题已部分解决。如果用户导航到localhost:2000,他将被重定向到主页。现在我们需要附加其他链接:
paths.forEach(function(prop) {
app.get(prop.path, function(req, res) {
res.redirect('/');
res.sendFile(__dirname + '/client/index.html');
const io = req.app.get('socketio');
const socketId = [];
io.on('connection', function(socket) {
socketId.push(socket.id);
if(socketId[0] === socket.id) {
io.removeAllListeners('connection');
}
socket.emit('renderPage', {page: prop.page});
// other listeners, login, register, etc...
});
});
});
因此,首先存在一个错误,如果您不断刷新页面,则该错误会一遍又一遍地呈现相同的项目并将其堆叠,但是if(socketId[0] === socket.id)
检查可以解决此问题。
现在,我们需要在客户端上执行的唯一操作是:
socket.on('renderPage', function(data) {
history.pushState({id: data.page}, '', `/pages/${data.page}`);
pages[data.page]();
});
其余的工作由客户来完成。我不认为这是最好的方法,但是它确实有效,并且由于我的时间不多,因此现在必须这样做。
任何有关改善此问题的建议都非常感谢!我只是Node的初学者,我实际上不明白为什么这样做。这全都归功于良好的旧尝试和错误。
TFW,您意识到您可以只在客户端执行window.location并从那里进行路由。我什至不需要表达了。好的XD,当整个宇宙中有最简单的解决方案时,我简直不敢相信自己总是会做出极其困难/不可能的事情。