簡體   English   中英

將數據傳遞給客戶端JavaScript(最好不帶視圖引擎或cookie)

[英]Pass data to client-side JavaScript (preferably without view engine or cookies)

第一部分:問題介紹

簡短的故事:我需要將數據從服務器傳遞到客戶端,但這些數據不需要在客戶端顯示。 相反,客戶端套接字使用數據來加入正確的房間。 轉到第二部分:解決方案嘗試

長篇故事:

對於我的第一個Web開發項目,我正在嘗試創建一個遠程演示者(即使用移動設備來控制桌面上的Google幻燈片演示文稿)。

在前端,我一直使用普通的舊HTMl,CSS和vanilla JS,而后端涉及NodeJS,Express框架和Socket.io。

以下是用戶流程的簡要概述:當用戶通過桌面上的Google登錄進行身份驗證時,網站將打開一個套接字連接,該連接會自動加入由套接字ID標識的房間。 在用戶登錄桌面端之后,用戶將(現在)將此套接字ID視為可用於在移動端登錄的“密鑰”。

因此,我有一個server.js來處理路由和表單操作(即在移動端提交的密鑰),如下所示:

// Store all the currently connected web clients
var webClients = [];

// Index route -- home page for website and mobile site
app.get('/', function (req, res) {
  // Basic user agent check - test for mobiles
  var userAgent = req.headers['user-agent'];
  if (/mobile/i.test(userAgent)) {
      // Send mobile to the mobile login site
      res.sendFile(__dirname + '/pages/mobile.html');
  } else {
      // Send desktop to the main site
      res.sendFile(__dirname + '/pages/index.html');
  }
});

// Dealing with secret key input
app.post('/secretKey', function(req, res) {

    // Store the secret key in a variable first
    var secretKey = req.body.secretKey;

    // Check if the secret key matches with any key in the database (current session)
    var index = webClients.indexOf(secretKey);

    // Send the user to the mobile controls if there is something that matches
    if (index != -1) {
        res.sendFile(__dirname + '/pages/mobileControl.html');
    } else {
        res.redirect('/');
    }
  }

});

不幸的是,我遇到了麻煩。 加載移動控件頁面后,將在移動端打開另一個套接字實例。 為了確保移動設備正在控制正確的演示文稿,我需要讓移動端的套接字加入與桌面套接字相同的房間(即具有桌面套接字ID的房間)。 因此,我需要將桌面套接字ID傳遞到移動端,以便移動套接字可以連接到正確的房間。

第二部分:解決方案嘗試

我知道其他幾個用戶已經在SO上提出了類似的問題。 例如:

從這些方面,我可以總結幾個突出的建議:

  1. 使用模板系統,如Jade,ejs等

我查看了Jade和ejs,我不願意使用這些模板系統,因為我懷疑它們可能對我在這里想要實現的內容有點過分 - 只需將一個字符串從服務器傳遞到客戶端JavaScript而不在其中呈現字符串視圖。 此外,我並不真正需要這些模板系統提供的部分功能,進一步強化了我的信念,即這些可能是過度的。

  1. 將數據存儲在cookie中,並在客戶端JavaScript上訪問cookie

目前,這個解決方案對我來說最吸引人,因為它似乎是最簡單的方法。 我可以簡單地做一些事情:

var options = {
     headers: {
          'set-cookie' : roomId=secretKey
     }
  };
res.sendFile(__dirname + '/pages/mobileControl.html', options);

然后,我可以通過執行document.cookiemobileControl.js的操作來訪問mobileControl.js中cookie中的數據。 但是,我已經讀過這種方法存在安全問題,例如跨站點腳本(XSS)攻擊。 因此,我也不願意使用這種方法。

  1. 將數據發送到另一個路由,並在呈現html后使用XMLHttpRequest檢索數據

除了這三種方法之外,我還研究了實現用戶會話,但我認為這不是我的解決方案,因為用戶會話可能會在稍后階段進入以允許登錄持續存在。

那么,您認為我應該在這種情況下使用哪種方法? 我應該跟2一起調整,並調整cookie的HttpOnly字段嗎? 還有其他建議嗎? 非常感謝!

如果你不想使用一個完整的模板引擎(盡管我認為這不會超過這個 - 這就是模板引擎的用途),那么只需要替換一個字符串呢?

放點像

<script>var SECRET_KEY = '{{{SECRET_KEY}}}';</script>

在您的HTML文件中,流式傳輸文件而不是發送它,並使用像stream-replace這樣的東西用您的密鑰替換{{{SECRET_KEY}}}字符串。

未經測試的例子:

var fs = require('fs');
var replace = require('stream-replace');

app.post('/secretKey', function(req, res) {

    // Store the secret key in a variable first
    var secretKey = req.body.secretKey;

    // Check if the secret key matches with any key in the database (current session)
    var index = webClients.indexOf(secretKey);

    // Send the user to the mobile controls if there is something that matches
    if (index != -1) {
        fs.createReadStream(__dirname + '/pages/mobileControl.html')
            .pipe(replace('{{{SECRET_KEY}}}', secretKey))
            .pipe(res);
    } else {
        res.redirect('/');
    }
});

然后,您將能夠在腳本中使用SECRET_KEY變量。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM