使用source-map实现对已压缩发布的前端代码的异常捕获与记录

使用source-map实现对已压缩发布的前端代码的异常捕获与记录

代码压缩和依赖管理使用webpack

 

https://www.npmjs.com/package/source-map

npm install source-map --save-dev

(因为用了webpack组织代码,所以都可以放在-dev里了)

在前端部署该代码,并且在公共依赖包中添加以下内容:

复制代码

import sourceMap from "source-map";

window.addEventListener("error", function (errorMessage, scriptURI, lineNumber, columnNumber, errorObj) {
    getMap(errorMessage.filename + ".map", function (data) {
        let smc = new sourceMap.SourceMapConsumer(data);
        let originPos = smc.originalPositionFor({
            line: errorMessage.lineno,
            column: errorMessage.lineno
        });
        let xhr = errorMessage.error.xhr || {};
        let errMes = {
            message: errorMessage.message,
            filename: errorMessage.filename,
            scriptURI: scriptURI,
            lineNo: originPos.line,
            colNo: originPos.column,
            errorObj: errorObj,
            xhr:{
                ...xhr,
                status:xhr.status,
                statusText:xhr.statusText,
                withCredentials:xhr.withCredentials
            }
        };
        window.fetch("http://localhost:30010/error", {
            method: "POST",
            body: JSON.stringify(errMes),
            headers: {"Content-Type": "application/json"}
        }).then(function (res) {
            console.log(res);
            res.json().then(function (data) {
                console.log(data);
            });
        });
    });
});

function getMap(path,fn) {
    fetch(path, {method: "GET"}).then(function (res) {
        res.json().then(fn)
    });
}

 

上述代码将在异常发生的时候,读取发生异常的文件对应的.map文件,然后通过source-map包中的new sourceMap.SourceMapConsumer来获取真正的行列号,然后将其发送至固定的服务器,我设置成了http://localhost;30010/error

对应的数据接收和处理的nodejs服务器代码如下:

"use strict";

const express = require('express');
const app = express();
const bodyParser = require("body-parser");
const fs = require("fs");
const path = require("path");


// parse application/x-www-form-urlencoded
app.use(bodyParser.urlencoded({ extended: true }));

// parse application/json
app.use(bodyParser.json());

app.all('*', function (req, res, next) {
    let allowedOrigins = [
        "http://localhost:8080",
        "http://localhost:12344",
        "http://localhost:3313",
        "http://localhost:63342"
    ];
    // 这里是允许跨域的的domain列表

    let origin = req.headers.origin;
    if(allowedOrigins.indexOf(origin) > -1){
        res.setHeader('Access-Control-Allow-Origin', origin);
    }

    res.header('Access-Control-Allow-Credentials', true);// Allow Cookie
    res.header("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept");
    res.header("Access-Control-Allow-Methods", "PUT,POST,GET,DELETE,OPTIONS");
    next();
});

app.post("/error", function (req,res) {
    console.log(req.body);
    let fileName = (new Date()).toLocaleDateString().split("/").join("_") + ".txt";
    let pathName = path.join(__dirname,"/log/" + fileName);
    fs.readdir("log", function (err,data) {
        console.log(err);
        console.log(data);
        let a;
        if (err != null) {
            fs.mkdir("log");
            a = -1;
        } else {
            a = data.findIndex(function (item) {
                console.log(item);
                console.log(fileName);
                return item == fileName;
            });
        }

        console.log(a);

        req.body.time = (new Date()).toLocaleTimeString();
        let logData = JSON.stringify(req.body) + ",,,\n";
        if (a != -1) {
            fs.appendFile(pathName,logData,"utf-8", function (err) {
                res.writeHead(200,{
                    "Content-Type":"text/plain;charset=utf-8"
                });
                res.end(JSON.stringify({status:"接受异常"}));
            });
        } else {
            fs.writeFile(pathName,logData,"utf-8", function (err) {
                res.writeHead(200,{
                    "Content-Type":"text/plain;charset=utf-8"
                });
                res.end(JSON.stringify({status:"接受异常"}));
            });
        }
    });

    //res.writeHead(200,{
    //    "Content-Type":"text/plain;charset=utf-8"
    //});
    //res.end(JSON.stringify({status:"接受异常"}));
});

app.listen(30010);

当然也可以把使用source-map解析.map文件得到行列号的操作在服务器进行,只要服务器读取本地的.map文件就可以了。

因为我用了webpackServer,所以在一开始为了方便就把原始行列号的获取写在客户端了。实际部署中这一步肯定是要在服务端的。因为map文件太大了。。。

转载地址:https://www.cnblogs.com/Totooria-Hyperion/p/5799494.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值