- 不支持 import
node需要使用require
- 热更新
前端开发的时候使用webpack
可以很方便地实现热更新,但node
我不知如何使用webpack
。所以,使用了pm2
。
pm2 start ./bin/www --watch
- 获取请求路径
req.url // 获取的是端口后之后的请求路径
- Error: Can’t set headers after they are sent.
对于一次请求,服务器多次响应就会发生这样的错误。解决方法是,next()
、send()
、end()
这些方法之前添加return
,防止之后的语句对请求做出响应。 - url
这个模块可以让 url 相关操作更简单。
// 比如 url.parse(req.url) 可以得到如下的结果 // 原始的 req.url 是包括参数之类的,但处理之后可以获得pathname 这样纯粹的路径 Url { protocol: null, slashes: null, auth: null, host: null, port: null, hostname: null, hash: null, search: '?q3', query: { q3: '' }, pathname: '/register/account/login', path: '/register/account/login?q3', href: '/register/account/login?q3' }
- 跨域
app.all("*",function(req,res,next){ //设置允许跨域的域名,*代表允许任意域名跨域 res.header("Access-Control-Allow-Origin","*"); //允许的header类型 res.header("Access-Control-Allow-Headers","content-type"); //跨域允许的请求方式 res.header("Access-Control-Allow-Methods","DELETE,PUT,POST,GET,OPTIONS"); if (req.method.toLowerCase() == 'options') res.send(200); //让options尝试请求快速结束 else next(); })
- 请求体太大
request entity too large
这种错误在上传文件的时候可能遇到,比如base64
格式的图片。
app.use(express.json({ limit: '50mb' })); app.use(express.urlencoded({ limit: '50mb', extended: false }));
https://blog.csdn.net/y75475/article/details/86716308
- base64 转图片存储
/** * 将base64转成图片存储 * @param {string} path * @param {string} base64 */ const base64ToFile = async (path, base64) => { const reg = /^data:image\/\w+;base64,/ let str = base64.replace(reg, '') str = str.replace(/\s/g, '+') let dataBuffer = new Buffer(str, 'base64') return new Promise((resolve, reject) => { fs.writeFile(path, dataBuffer, (err) => { if (err) { console.log(err) resolve({ status: false, errorMsg: err }) } else { resolve({ status: true, path }) } }) }) } /** * 分析字符串,如果是base64就按照参数存储 * @param {string} basePath 基本路径 * @param {string} fileName 文件名,不包含后缀 * @param {string} base64 字符串 */ const strToImageFile = async (basePath, fileName, base64) => { const reg = /^data:image\/\w+;base64,/ return new Promise( async (resolve, reject) => { if (reg.test(base64)) { const matchs = base64.match(/^(data:image\/(\w+);base64,)/) if (matchs) { const type = matchs[2] let path = basePath + fileName + '.' + type const res = await base64ToFile(path, base64) resolve(res) } else { resolve({ status: false, errorMsg: '无效的图片格式' }) } } else { resolve({ status: true, path: base64 }) } }) }
- 请求内(外)部接口
碰到需要请求内(外)部接口的情况,可以使用axios
(request
停止维护了)。使用方法和前端一样,可以用axios.get(xxx).then()
,也可以使用await axios.get(xxxx)
,后端可能偏向后一种方法,但最好配合try……catch……
使用。
请求内部接口的url
,我用的是http://localhost:3000/xxx
这样的。 app.use()
路径使用*
和/
的区别
具体的我也不清楚。从碰到的问题来看,使用*
的话,req.url
会变成/
,即真实路径会丢失,而使用/
则不会丢失。- 获取全部路由
因为我的鉴权中间件是最先执行的,这时需要知道请求的路径是否存在,否则会统一当作没有权限的接口处理。虽然也没太大影响,但不优雅。而express
框架是不会告诉中间件应用的所有路由的。在网上找到的解决方法是解析app._router.stack
获取全部路由。
// utils.js /** * 获取全部路由--在 app.js 中使用 */ const listRoutes = (routes = [], stack, parent) => { parent = parent || ''; stack.forEach(function(r){ if (r.route && r.route.path){ var method = ''; for(method in r.route.methods){ if(r.route.methods[method]){ routes.push({method: method.toUpperCase(), path: parent + r.route.path}); } } } else if (r.handle && r.handle.name == 'router') { const routerName = r.regexp.source.replace("^\\","").replace("\\/?(?=\\/|$)",""); return listRoutes(routes, r.handle.stack, parent + routerName); } }); return routes; } module.exports = { listRoutes } // app.js const { listRoutes } = require('./utils/utils') …… // 获取全部路由--在 app.use 之后执行 global.routes = listRoutes([], app._router.stack) // 这样,在需要全部路由的中间件里就可以通过 global.routes 获取路由了。
- SyntaxError: Cannot use import statement outside a module
node 早起只支持 CommenJS 模块,v13.2.0 之后才支持 ES6 对模块,不过需要 package.json 里添加 “type”: “module”。但这会导致 ./bin/www 执行报错:ERR_UNKNOWN_FILE_EXTENSION。所以暂时不用 ES6 模块好了。 - 写入文件
const fs = require('fs') // 1. 异步写入 json 文件 // JSON.stringify 的第二三个参数可以让 json 字符串美观一点,不至于压缩在一行。 // https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify fs.writeFile('file.json', JSON.stringify(data, null, '\t')) // 2. 同步写入 json 文件 fs.writeFileSync('file.json', JSON.stringify(data, null, '\t')) // 2. 打开文件再写入 const fd = fs.openSync('file.json', 'w') fs.writeSync(fd, JSON.stringify(data, null, '\t'))