使用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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章