在特定視圖中可存取的變數稱為 locals
。區域變數代表伺服器端資料,這些資料是您的視圖可以存取的——除非您使用視圖引擎提供的特殊語法明確地引用它們,否則區域變數實際上並不會包含在編譯後的 HTML 中。
<div>Logged in as <a><%= user.fullName %></a>.</div>
存取區域變數的符號在不同的視圖引擎之間有所不同。在 EJS 中,您可以使用特殊的模板標記(例如 <%= someValue %>
)將區域變數包含在您的視圖中。
EJS 中有三種模板標籤
<%= someValue %>
someValue
區域變數進行 HTML 逸出,然後將其作為字串包含進來。<%- someRawHTML %>
someRawHTML
區域變數,而不進行逸出。<% if (!loggedIn) { %> <a>登出</a> <% } %>
<% ... %>
內的 JavaScript。if
/else
) 和遍歷資料 (for
/each
)。以下是一個視圖 (views/backOffice/profile.ejs
) 使用兩個區域變數 user
和 corndogs
的範例
<div>
<h1><%= user.fullName %>'s first view</h1>
<h2>My corndog collection:</h2>
<ul>
<% for (let corndog of corndogs) { %>
<li><%= _.capitalize(corndog.name) %></li>
<% } %>
</ul>
</div>
您可能已經注意到另一個區域變數:
_
。預設情況下,Sails 會自動將一些區域變數傳遞到您的視圖,其中之一是 lodash (_
)。
如果您想要傳遞到此視圖的資料是完全靜態的,您不一定需要控制器。相反地,您可以將視圖及其區域變數硬編碼在您的 config/routes.js
檔案中,如下所示
// ...
'get /profile': {
view: 'backOffice/profile',
locals: {
user: {
fullName: 'Frank',
emailAddress: '[email protected]'
},
corndogs: [
{ name: 'beef corndog' },
{ name: 'chicken corndog' },
{ name: 'soy corndog' }
]
}
},
// ...
但更可能的情況是,這些資料將是動態的。在這種情況下,我們需要使用控制器動作從我們的模型載入資料,然後使用 res.view() 方法將其傳遞給視圖。
假設我們將我們的路由連接到我們控制器的一個動作(並且我們的模型已設定好),我們可能會像這樣傳送我們的視圖
// in api/controllers/UserController.js...
profile: function (req, res) {
// ...
return res.view('backOffice/profile', {
user: theUser,
corndogs: theUser.corndogCollection
});
},
// ...
exposeLocalsToBrowser
逸出不受信任的資料通常希望將資料「引導」到頁面上,以便在頁面載入後立即通過 Javascript 存取,而無需在單獨的 AJAX 或 socket 請求中獲取資料。像 Twitter 和 GitHub 這樣的網站大量依賴這種方法,以優化頁面載入時間並提供更佳的使用者體驗。
從歷史上看,這個問題通常通過使用隱藏表單欄位或手動編寫程式碼將伺服器端區域變數直接注入到客戶端腳本標籤中來解決。雖然這些技術有效,但當要引導的某些資料來自不受信任的來源時,這些技術可能會帶來挑戰,這些來源可能包含 HTML 標籤和 Javascript 程式碼,旨在通過 XSS 攻擊 來危害您的應用程式。為了防止這種情況,Sails 提供了一個內建的視圖局部範本,稱為 exposeLocalsToBrowser
,您可以使用它安全地從您的視圖區域變數中注入資料,以便從客戶端 JavaScript 存取。
要使用 exposeLocalsToBrowser
,只需使用您的模板語言的非逸出語法從您的視圖中呼叫它即可。例如,使用預設的 EJS 視圖引擎
<%- exposeLocalsToBrowser() %>
預設情況下,這會將所有您的視圖區域變數公開為 window.SAILS_LOCALS
全域變數。例如,如果您的動作程式碼包含
res.view('myView', {
someString: 'hello',
someNumber: 123,
someObject: { owl: 'hoot' },
someArray: [1, 'boot', true],
someBool: false
someXSS: '<script>alert("all your credit cards belong to me!!");</script>'
});
那麼如上所示使用 exposeLocalsToBrowser
將導致區域變數以安全的方式引導,使得 window.SAILS_LOCALS.someArray
將包含陣列 [1, 'boot', true]
,並且 window.SAILS_LOCALS.someXSS
將包含字串 <script>alert("all your credit cards belong to me!!");</script>
,而不會導致該程式碼實際在頁面上執行。
exposeLocalsToBrowser
函數有一個單一的 options
參數,可用於配置輸出哪些資料以及如何輸出。 options
參數是一個字典,可以包含以下屬性
屬性 | 類型 | 預設值 | 詳細資訊 | |
---|---|---|---|---|
1 | keys | undefined |
要公開的區域變數的「白名單」。如果留為 undefined,將公開所有區域變數。如果指定,這應該是來自區域變數字典的屬性名稱陣列。例如,給定上面顯示的 res.view() 語句,設定 keys: ['someString', 'someBool'] 將導致 windows.SAILS_LOCALS 被設定為 {someString: 'hello', someBool: false} 。 |
|
2 | namespace | SAILS_LOCALS |
應將引導資料分配給的全域變數的名稱。 | |
3 | dontUnescapeOnClient | false | 進階。不建議大多數應用程式使用。 如果設定為 true ,為了避免 XSS 攻擊而逸出的任何字串值在從客戶端 JS 存取時仍然會被逸出,而不是轉換回原始值。例如,給定上面範例中的 res.view() 語句,使用 exposeLocalsToBrowser({dontUnescapeOnClient: true}) 將導致 window.SAILS_LOCALS.someXSS 被設定為 <script>alert('hello!'); 。 |