- 不支持 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'))