# node-http-demo **Repository Path**: yanhsama/node-http-demo ## Basic Information - **Project Name**: node-http-demo - **Description**: node实现一个小型后端服务 - **Primary Language**: NodeJS - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 1 - **Forks**: 0 - **Created**: 2024-07-05 - **Last Updated**: 2024-11-26 ## Categories & Tags **Categories**: Uncategorized **Tags**: Node, Nodejs, JavaScript ## README # http 请求 node 版本 16.16.0 node 版本 18.16.0 会连接 MongoDB 数据库错误。 ```shell Connected to MongoDB failed MongoServerSelectionError: connect ECONNREFUSED ::1:27017 ``` ```json { "name": "http-node-demo", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "start": "node index.js" }, "author": "", "license": "ISC", "type": "module", "dependencies": { "body-parser": "^1.20.2", "mongodb": "^6.8.0", "querystring": "^0.2.1" } } ``` 项目安装 MongoDB 的 node 版本要跟启动时的 node 版本一致,否则会报错 ```js const timeoutError = new error_1.MongoServerSelectionError( `Server selection timed out after ${options.serverSelectionTimeoutMS} ms`, this.description ); ``` ## node 链接 MongoDB ```js // MongoDB连接配置 const mongoConfig = { url: "mongodb://localhost:27017", dbName: "note", //数据库名称 }; ``` ```js import { MongoClient } from "mongodb"; import { mongoConfig } from "./default.js"; const mongoDB = new MongoClient(mongoConfig.url); let db; async function mainFun() { // 创建MongoDB连接 try { await mongoDB.connect(); console.log("Connected to MongoDB successfully"); db = mongoDB.db(mongoConfig.dbName); } catch (err) { console.log("Connected to MongoDB failed", err); } } export { mainFun, db }; ``` ## 接口返回的形势 - 返回 404 ```js // 解析url const urlObj = new URL(req.url, `http://${req.headers.host}`); const params = {}; const apiKey = `${urlObj.pathname}&${req.method.toLocaleLowerCase()}`; const item = ALL_PATH.find((v) => `/${v}` == apiKey); // 找不到路由,返回404 Not Found if (!item) { res .writeHead(404, { "Content-Type": "text/plain; charset=utf-8", }) .end("Not Found"); return; } ``` - 普通 JSON 字符串 ```js import { db } from "../mongoDB/index.js"; const getUser = async () => { try { // 查询数据集合user的所有数据并转为数组形式 const collection = await db.collection("user").find({}).toArray(); let total = 0; collection.estimatedDocumentCount(function (err, count) { if (err) throw err; total = count; console.log("Estimated total number of documents: ", count); // client.close(); }); return { code: 200, data: { list: collection, total: total || 0, }, }; } catch (err) { return { code: 500, data: { list: [], total: 0, }, }; } }; ``` - 返回文件流 ```js import fs from "fs"; import path from "path"; const __dirname = path.resolve(); const downloadDocs = async () => { const promise = new Promise((resolve, reject) => { fs.readFile(__dirname + "/docs/新建文本文档.txt", (err, data) => { if (err) { console.error(err); reject("error"); return; } resolve(data); }); }); try { const resData = await promise; return { code: 200, data: resData, contentType: "text/plain; charset=utf-8", }; } catch (err) { return { code: 500, data: "", contentType: "text/plain; charset=utf-8", }; } }; const downloadNoteTemplate = async () => { try { const data = fs.readFileSync(__dirname + "/docs/Note模板.xlsx"); return { code: 200, data: data, contentType: "application/vnd.ms-excel; charset=utf-8", }; } catch (err) { return { code: 500, data: "", contentType: "application/vnd.ms-excel; charset=utf-8", }; } }; ``` ```shell resData { code: 200, data: , contentType: 'text/plain; charset=utf-8' } ``` ## 响应头 当标头已使用 `response.setHeader()` 设置时,则它们将与任何传给 `response.writeHead() `的标头合并,其中传给` response.writeHead()` 的标头优先。 语法 ```js response.writeHead(statusCode[, statusMessage][, headers]) response.setHeader('Content-Type', 'text/html'); response.setHeader('Set-Cookie', ['type=ninja', 'language=javascript']); ``` ```js // Returns content-type = text/plain const server = http.createServer((req, res) => { res.setHeader("Content-Type", "text/html"); res.setHeader("X-Foo", "bar"); res.writeHead(200, { "Content-Type": "text/plain" }); res.end("ok"); }); ``` ## 返回 xlsx 文件,前端下载处理 后端接口 ```js const downloadNoteTemplate = async () => { try { const data = fs.readFileSync(__dirname + "/docs/Note模板.xlsx"); return { code: 200, data: data, contentType: "application/vnd.ms-excel; charset=utf-8", }; } catch (err) { return { code: 500, data: "", contentType: "application/vnd.ms-excel; charset=utf-8", }; } }; ``` 前端下载处理 ```js ``` ```js export const downloadContentFileFun = (filename, text) => { // 下载Excel的文件, type: "application/vnd.ms-excel"需要与后端返回的content保持一致,否则会出现无法打开的情况 let blob = new Blob([text], { type: "application/vnd.ms-excel" }); const element = document.createElement("a"); const href = URL.createObjectURL(blob); element.href = href; element.setAttribute("download", filename); element.style.display = "none"; element.click(); //调用这个方法来让浏览器知道不用在内存中继续保留对这个文件的引用了。 URL.revokeObjectURL(href); element.remove(); }; ``` ## 返回 txt 文件,前端下载处理 后端接口 ```js const downloadDocs = async () => { const promise = new Promise((resolve, reject) => { fs.readFile(__dirname + "/docs/新建文本文档.txt", (err, data) => { if (err) { console.error(err); reject("error"); return; } resolve(data); }); }); try { const resData = await promise; return { code: 200, data: resData, contentType: "text/plain; charset=utf-8", }; } catch (err) { return { code: 500, data: "", contentType: "text/plain; charset=utf-8", }; } }; ``` 前端下载处理 ```js ``` ```js export const downloadContentFileFun = (filename, text) => { // 这里的类型type改成application/vnd.ms-excel,发现也是可以正常打开的 let blob = new Blob([text], { type: "text/plain; charset=utf-8" }); const element = document.createElement("a"); const href = URL.createObjectURL(blob); element.href = href; element.setAttribute("download", filename); element.style.display = "none"; element.click(); //调用这个方法来让浏览器知道不用在内存中继续保留对这个文件的引用了。 URL.revokeObjectURL(href); element.remove(); }; ``` 关于前端下载文件的一些方法:https://blog.csdn.net/weixin_40119412/article/details/126980329 ## node 利用 excelJS 导出文件 ```js //exportExcel\excel.js // 导入 import ExcelJS from "exceljs"; export default () => { // 创建工作薄 const workbook = new ExcelJS.Workbook(); // 设置工作簿属性 workbook.creator = "System"; workbook.lastModifiedBy = "System"; workbook.created = new Date(2024, 7, 3); workbook.modified = new Date(); workbook.lastPrinted = new Date(2024, 7, 3); // 将工作簿日期设置为 1904 年日期系统 workbook.properties.date1904 = true; // 在加载时强制工作簿计算属性 workbook.calcProperties.fullCalcOnLoad = true; workbook.views = [ { x: 0, y: 0, width: 1000, height: 2000, firstSheet: 0, activeTab: 1, visibility: "visible", }, ]; return workbook; }; ``` ```js //exportExcel\index.js import workbookFun from "./excel.js"; export default async (data, columns, sheetName = "sheet1") => { const workbook = workbookFun(); // 添加工作表 const sheet = workbook.addWorksheet(sheetName); sheet.columns = columns; // 将数据添加到工作表中 sheet.addRows(data); // 后端 node返回接口直接使用buffer流 const bufferData = await workbook.xlsx.writeBuffer(); // 浏览器可以利用Blob下载文件 ;node直接返回Blob会提示错误 // const blob = new Blob([bufferData], { // type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' // }); return bufferData; }; ``` 利用 exceljs 库和 buffer.Blob 返回数据出错 原因 不支持返回 Blob 格式的数据,只支持字符串类型或 Buffer or Uint8Array ```js (Use `node --trace-warnings ...` to show where the warning was created) ErrorCaptureStackTrace(err); ^ TypeError [ERR_INVALID_ARG_TYPE]: The "chunk" argument must be of type string or an instance of Buffer or Uint8Array. Received an instance of Blob ``` ## MongoDB 操作 查看集合 ```shell show collections; ``` 返回信息 ```shell user_table role_table ``` 删除一个集合 ```shell db.user_table.drop(); ``` 创建一个集合 ```shell db.createCollection('template_table') ```