Как заставить пользовательский URL выполнять клиентский JavaScript?(СПА) - PullRequest
0 голосов
/ 13 октября 2018

Я создаю электронную коммерцию и по какой-то причине я хотел, чтобы это была SPA.Теперь, когда я почти закончил, пути назад уже нет.

Сначала я построил историю, используя, ну что же, history.pushState и popstate.И навигация вперед и назад работает отлично, и молниеносно быстро.

Дело в том, что если пользователь переходит к разделу ЦП, 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, и отображаетстр.Однако, когда он приземляется, сокет-соединение закрывается, и вход / регистрация и другие вещи становятся непригодными.Этот подход хорош?Это нормально, если я помещаю свои логин, регистр и другие события сокета в событие подключения IO внутри app.get?Есть ли какая-то основа для этого, так как я не думаю, что экспресс сделан для этого короля работы ..

Спасибо!

1 Ответ

0 голосов
/ 16 октября 2018

Хорошо, я играл с этим пару недель, и мне удалось заставить его работать.

Прежде всего, создайте массив со всеми 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]();
});

А клиент сделает все остальное.Я не верю, что это лучший метод, но он работает, и, так как у меня мало времени, он должен сделать это сейчас.

Любая рекомендация по улучшению этого очень ценится!Я просто новичок в узле, и я на самом деле не понимаю, почему это работает.Это все благодаря старым добрым методам проб и ошибок.


TFW вы понимаете, что можете просто выполнить window.location на стороне клиента и выполнить оттуда маршрутизацию.Мне даже не нужно больше выражать.Хороший XD Я не могу поверить, что я всегда склонен делать что-то чрезвычайно сложное / невозможное, когда во всей вселенной есть самое простое решение ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...