前端监控页面报错及接口报错,上传报错到服务器日志
1.前端代码
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Demo</title>
</head>
<body>
<button id="promiseError">抛出 Promise 错误</button>
<button id="timeoutError">抛出定时器错误</button>
<button id="undefinedError">抛出未定义变量错误</button>
<button id="networkError">抛出网络请求错误</button>
<button id="domError">抛出 DOM 操作错误</button>
<button id="syntaxError">抛出语法错误</button>
<button id="typeError">抛出类型错误</button>
<script>
function reportError(error) {
console.log(error, 'error');
const utcDate = new Date();
const beijingDate = new Date(utcDate.getTime() + 8 * 60 * 60 * 1000); // 获取北京时间
fetch('/api/error-report', {
method: 'POST',
body: JSON.stringify({
error: error.message,
stack: error.stack,
timestamp: beijingDate.toISOString(),
}),
headers: { 'Content-Type': 'application/json' }
})
.then(response => console.log('错误已上报:', response.status))
.catch(err => console.error('上报失败:', err));
}
// Promise 错误
document.getElementById('promiseError').addEventListener('click', function () {
new Promise((resolve, reject) => {
console.log(notdefined);
resolve();
})
// .catch(err => {
// reportError(err);
// });
});
// 定时器错误
document.getElementById('timeoutError').addEventListener('click', function () {
setTimeout(() => {
throw new Error("定时器错误");
}, 1000);
});
// 未定义变量错误
document.getElementById('undefinedError').addEventListener('click', function () {
console.log(nonExistentVariable);
});
// 网络请求错误
document.getElementById('networkError').addEventListener('click', function () {
fetch('/data') // 触发404或其他网络错误
.then(response => {
if (!response.ok) {
throw new Error('网络请求错误: ' + response.status);
}
return response.json();
})
.then(r => {
console.log(r);
})
// .catch(error => {
// reportError(error);
// });
});
// DOM 操作错误
document.getElementById('domError').addEventListener('click', function () {
document.getElementById('nonExistentElement').innerText = 'Hello World';
});
// 语法错误
document.getElementById('syntaxError').addEventListener('click', function () {
eval('alertThis will throw a syntax error')
});
// 类型错误
document.getElementById('typeError').addEventListener('click', function () {
const obj = null;
console.log(obj.someProperty);
});
// 全局错误处理
window.onerror = function (msg, url, lineNo, columnNo, error) {
console.log(111);
reportError(error || new Error(msg));
};
window.addEventListener('unhandledrejection', function (event) {
reportError(event.reason);
});
// vue错误监听 项目中添加以下代码即可
// Vue.config.errorHandler = function (err, vm, info) {
// reportError(err);
// };
// function reportError(error) {
// console.log(error, 'error');
// const utcDate = new Date();
// const beijingDate = new Date(utcDate.getTime() + 8 * 60 * 60 * 1000); // 获取北京时间
// fetch('http://localhost:3000/api/error-report', {
// method: 'POST',
// body: JSON.stringify({
// error: error.message,
// stack: error.stack,
// timestamp: beijingDate.toISOString(),
// }),
// headers: { 'Content-Type': 'application/json' }
// })
// .then(response => console.log('错误已上报:', response.status))
// .catch(err => console.error('上报失败:', err));
// }
// // 全局错误处理
// window.onerror = function (msg, url, lineNo, columnNo, error) {
// console.log('window.1111');
// reportError(error || new Error(msg));
// };
// window.addEventListener('unhandledrejection', function (event) {
// reportError(event.reason);
// });
</script>
</body>
</html>
2.服务代码
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
const path = require("path");
const fs = require("fs");
const app = express();
app.use(bodyParser.json());
app.use(cors()); // 允许所有跨域请求
// 设置静态资源目录
app.use(express.static(path.join(__dirname, 'public')));
// 处理根路由,返回 index.html
app.get('/data', (req, res) => {
res.status(500).send({msg: "1223"});
});
// 处理错误报告
// app.post('/api/error-report', (req, res) => {
// console.log('收到错误报告:', req.body);
// // 这里可以将错误记录到数据库或日志文件中
// res.status(200).send('错误已接收');
// });
app.post('/api/error-report', (req, res) => {
const errorMessage = req.body; // 获取错误信息
// 获取错误的堆栈信息
const today = new Date();
const year = today.getFullYear(); // 获取年份
const month = String(today.getMonth() + 1).padStart(2, '0'); // 获取月份,注意要加1,并补零
const day = String(today.getDate()).padStart(2, '0'); // 获取日期,补零
const formattedDate = `${year}-${month}-${day}`;
const logFile = 'logs/errors'+formattedDate +'.log'; // 统一日志文件
// 确保日志目录存在
fs.mkdirSync(path.dirname(logFile), { recursive: true });
// 写入错误信息和堆栈到日志文件
const logEntry = `${new Date()}\n ${JSON.stringify(errorMessage)}\n`;
console.log(logEntry);
fs.appendFile(logFile, logEntry, (err) => {
if (err) {
console.error('写入日志失败:', err);
return res.status(500).send('日志记录失败');
}
console.log('收到错误报告:', req.body);
res.status(200).send('错误已接收');
});
});
// 获取服务器端口
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
console.log(`服务器正在监听 http://localhost:${PORT}`);
});
package.json
{
"dependencies": {
"cors": "^2.8.5",
"express": "^4.21.0"
}
}
原文地址:https://blog.csdn.net/songJunFeng1/article/details/142531143
免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!