【问题标题】:issue with serving static files with socket.io使用 socket.io 提供静态文件的问题
【发布时间】:2014-01-05 21:07:15
【问题描述】:

我正在创建一个用户可以登录的网络应用程序(密码/用户名)。登录后,他可以选择 2 个可用应用程序之一。 第一个应用程序在客户端和服务器之间使用 http 连接。 第二个使用网络套接字。所以当用户点击第二个应用程序时,应该建立一个 websocket。 我的第一个应用程序运行良好,第二个应用程序也运行良好,但是当我将所有应用程序放在一起时。我有问题。

这是我到目前为止所做的:

server.js

var app = express();
var server = http.createServer(app, function(req, res) {
  //serves static files
  //processes GET and POST requests of both the login page and the 1st app 
}

server.listen(80, function() {
   console.log("Server listening on port 80.");
}); 

app.configure(function () {
    app.use(express.cookieParser());
    app.use(express.session({secret: 'secret', key: 'express.sid'}));
});

 app.get('/', function (req, res) {
   var filePath = '../client/index.html';
   if (filePath){
      var absPath = './' + filePath;
      serveStatic(res, cache, absPath); //function that serves static files
   } 
}); 
io = io.listen(server);
io.set('authorization', function (handshakeData, accept) {
  //code
});

io.sockets.on('connection', function(socket) { 
  console.log('Client connected.');
});

index.html

    <script src="../third-party/jquery-1.9.1.min.js"></script>
    <script src="/socket.io/socket.io.js"></script>

<script>
    $(document).ready(function() {

    tick = io.connect();
          tick.on('data', function (data) {
              console.log(data);
          });

          tick.on('error', function (reason){
            console.error('Unable to connect Socket.IO', reason);
          });

          tick.on('connect', function (){
            console.info('successfully established a working and authorized connection');
          });
    });
</script>

在客户端,我使用 jquery。

当我连接到我的本地主机时,我得到登录页面,并且在 chrome 调试器工具上显示一条错误消息:$ 未定义(在 index.html 中),GET http://localhost/third-party/jquery-1.9.1.min.js 404 (Not Found)

这是我的应用程序的架构:

- server
   - server.js
-client
     -index.html (login page)
     -firstApp 
       -index.html
     -secondApp (uses websocket)   
         -index.html
     - third-party
         -jquery-1.9.1.min.js

我相信,我没有以正确的方式提供静态文件。虽然,在将 websocket 添加到我的代码之前,我对此没有任何问题。 我不明白的是当我在

下记录一些东西时
var server = http.createServer(app, function(req, res) {
   console.log('TEST')
});

控制台上没有显示任何内容。 以下是提供静态文件的函数的方式:

function sendFile(res, filePath, fileContents) {
   res.writeHead(200, {"content-type": mime.lookup(path.basename(filePath))});
   res.end(fileContents);
} 

function serveStatic(res, cache, absPath) {
   //checks if file is cached in memory
   if (cache[absPath]) {
      sendFile(res, absPath, cache[absPath]); //serves file from memory
   }else {
      fs.exists(absPath, function(exists) { //checks if file exists
         if (exists) { 
            fs.readFile(absPath, function(err, data) { //reads file from disk
               if (err) {
               }else {
                  cache[absPath] = data;
                  sendFile(res, absPath, data); //serves file from disk
               }
            });
         }else {
            console.log('cannot find the file')
            send404(res);
         }
      });
   }
} 

【问题讨论】:

    标签: jquery node.js express socket.io


    【解决方案1】:

    只需添加

    app.use( express.static(__dirname+'../client') );

    到你的中间件链,并从你的index.html请求文件到客户端目录,如下:

    secondApp/index.html

    <script src="/third-party/jquery-1.9.1.min.js"></script>
    <script src="/socket.io/socket.io.js"></script>
    

    express.static 是对connect.static 的引用

    恕我直言,请将您的 server.js 代码至少清理到

    var app = express()
      , server = http.createServer(app)
      , io = io.listen(server)
    ;
    
    app.configure(function () {
        app.use( express.cookieParser() );
        app.use( express.session({secret: 'secret', key: 'express.sid'}) );
        app.use( app.router )
        app.use( express.static(__dirname+'../client') );
    });
    
    
    app.get('/', function (req, res) {
        res.sendFile( __dirname+'../client/index.html' ) 
    });
    
    app.get('/whatever/url/path/you/want', function (req, res) {
        // this will match GET requests to /whatever/url/path/you/want
    });
    
    app.get('*', function (req, res) {
        // this will match GET requests to any path
        // take care if you use middlewares after app.router as here
    });
    
    app.post('/whatever/url/path/you/want', function (req, res) {
        // this will match POST requests to /whatever/url/path/you/want
    });
    
    app.post('*', function (req, res) {
        // this will match POST requests to any path
    });
    
    io.set('authorization', function (handshakeData, accept) {
    });
    
    io.sockets.on('connection', function(socket) { 
      console.log('Client connected.');
    });
    
    server.listen(80, function() {
       console.log("Server listening on port 80.");
    });
    

    警告:以上代码既不是最干净也不是最好的代码

    看看http.createServer documentation

    它只接受 1 个侦听器进行请求。您可以注册 2 个侦听器,但由于您使用的是 express,因此最好的方法是使用它的功能,请参阅上面 server.js 示例代码中的示例

    你不需要你提到的那些serveStatic 函数

    express.static 对你来说已经足够了。

    旁注

    您不需要在客户端将io.connect 包装在$.ready

    【讨论】:

    • 感谢您的回答。但我仍然有未定义 $ 的问题。您建议通过删除 createServer 中的回调函数来清理代码,但是我在其中提供静态文件。如果我需要服务第三方/jquery.js,app.get() 中的 req.url 应该记录第三方/jquery.js,这里不是这种情况。你可以看到我在 Paul Harris 回答下留下的评论
    • @user1499220 你不需要 createServer 中的额外回调函数。建议更改后,您只需更新 index.html 文件中脚本的 url。我已经编辑了我的答案,请看一下
    • 再次感谢您的回答。我确实喜欢你的建议,但我仍然有同样的错误。另外,firstApp/index.html 和 index.html 不使用socket.io,为什么我需要包含socket.io 源?关于 http.createServer,我需要回调函数来处理从 firstApp 和登录页面收到的 POST 和 GET 请求。如果我删除这个回调,我应该在哪里处理这些请求?
    • @user1499220 好的,我添加了一些关于使用 express 进行 POST 和 GET 路由的示例。你应该研究一下快递。我看到您提出基本问题,一旦知道答案将引导您在目标上取得成功。请关注express api docs,特别是the routing section
    猜你喜欢
    • 2015-12-15
    • 1970-01-01
    • 2019-04-17
    • 2017-11-24
    • 2021-07-14
    • 1970-01-01
    • 2013-10-17
    • 2011-01-27
    相关资源
    最近更新 更多