簡體   English   中英

Node.js Express 向客戶端 vanilla JS 發送大量數據

[英]Node.js Express send huge data to client vanilla JS

在我的應用程序中,我讀取了大量圖像數據,並將整個數據發送到客戶端:

const imagesPaths = await getFolderImagesRecursive(req.body.rootPath);
const dataToReturn = await Promise.all(imagesPaths.map((imagePath) => new Promise(async (resolve, reject) => {
    try {
        const imageB64 = await fs.readFile(imagePath, 'base64');

        return resolve({
            filename: imagePath,
            imageData: imageB64,
        });
    } catch {
        return reject();
    }
})));

return res.status(200).send({
    success: true,
    message: 'Successfully retreived folder images data',
    data: dataToReturn,
});

這是客戶端:

const getFolderImages = (rootPath) => {
    return fetch('api/getFolderImages', {
        method: 'POST',
        headers: { 'Content-type': 'application/json' },
        body: JSON.stringify({ rootPath }),
    });
};

const getFolderImagesServerResponse = await getFolderImages(rootPath);
const getFolderImagesServerData = await getFolderImagesServerResponse.json();

當我發送數據時,由於數據量大而失敗。 僅使用res.send(<data>)發送數據是不可能的。 那么,我該如何繞過這個限制——我應該如何在新進程中接受客戶端的數據?

您的問題的答案需要閱讀:

鏈接到解決方案

您之前可能沒有充分利用的一件事是網絡服務器的 http 響應默認為 stream。

它們只是讓您更容易傳遞同步數據,這些數據在后台被解析為塊並作為 HTTP 包發送。

我們在這里談論的是大文件; 自然,我們不希望它們存儲在任何 memory 中,至少不是整個 blob。 解決這個困境的最佳解決方案是 stream。

我們在內置節點 package 'fs' 的幫助下創建一個讀取流,然后將其傳遞給 stream 兼容的 response.send 參數。

const readStream = fs.createReadStream('example.png');
return response.headers({
  'Content-Type': 'image/png',
  'Content-Disposition': 'attachment; filename="example.png"',
}).send(readStream);

我在這里使用了 Fastify 網絡服務器,但它應該與 Koa 或 Express 類似地工作。

這里還有兩個配置:將 header 命名為“Content-Type”和“Content-Disposition”。

第一個指示我們逐塊發送的 blob 類型,因此前端會自動為其提供擴展名。

后者告訴瀏覽器我們正在發送附件,而不是可渲染的東西,例如 HTML 頁面或腳本。 這將觸發廣泛支持的瀏覽器下載功能。 filename 參數是內容的下載名稱。

我們到了; 我們實現了最小的 memory 壓力、最小的編碼和最小的錯誤機會。

我們還沒有提到的一件事是身份驗證。

事實上,前端不會發送 Ajax 請求,我們不能指望 auth JWT header 出現在請求中。

在這里,我們將采用良好的舊 cookie 身份驗證方法。 Cookies 根據 cookie 選項在符合條件的每個請求 header 上自動設置。 前端實現部分中有關此的更多信息。

默認情況下,cookies 以分號分隔的鍵值對形式出現在單個字符串中。 為了簡化解析部分,我們將使用 Fastify 的 Cookieparser 插件。

等待 fastifyServer.register(cookieParser); 稍后在處理程序方法中,我們只需獲取我們感興趣的 cookie 並將其與預期值進行比較。 這里我只使用字符串作為 auth-tokens; 這應該用某種散列和比較算法代替。

const cookies = request.cookies;
if (cookies['auth'] !== 'authenticated') {
   throw new APIError(400, 'Unauthorized');
}

而已。 我們在文件流端點之上進行了身份驗證,一切都准備好由前端連接。

暫無
暫無

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

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