如何使自定义URL执行客户端JavaScript? (温泉)

时间:2018-10-13 14:43:00

标签: node.js express socket.io

我正在建立一个电子商务,由于某种原因,我希望它成为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连接事件中可以吗? 有什么框架可以解决这个问题,因为我不认为表达是为这位工作之王准备的。

谢谢!

1 个答案:

答案 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,当整个宇宙中有最简单的解决方案时,我简直不敢相信自己总是会做出极其困难/不可能的事情。