Я создаю электронную коммерцию и по какой-то причине хотел, чтобы это был SPA. Теперь, когда я почти закончил, пути назад нет.
Сначала я построил историю, используя события history.pushState и popstate. И навигация вперед и назад работает нормально, причем очень быстро.
Дело в том, что если пользователь переходит в раздел ЦП, pushState создает следующую ссылку: localhost: 2000 / pages / cpu, и каждая страница имеет собственную «ссылку». Но если пользователь переходит на localhost: 2000 / pages / cpu express, возврат не может получить ошибку. Что очевидно.
Я действительно застрял, и единственное, что я смог придумать, это следующее:
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? Есть ли какие-то рамки для этого, так как я не думаю, что экспресс создан для этого короля работы ...
Спасибо!





Хорошо, я играл с этим пару недель, и мне удалось заставить его работать.
Перво-наперво создайте массив со всеми 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 Я не могу поверить, что всегда склонен делать что-то чрезвычайно сложное / невозможное, когда есть самое простое решение во всей вселенной ...
Вы не должны использовать window.location с историей api. Они не очень хорошо играют вместе