前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >移动端tryjs异常捕获

移动端tryjs异常捕获

作者头像
IMWeb前端团队
发布于 2017-12-29 09:02:51
发布于 2017-12-29 09:02:51
90100
代码可运行
举报
文章被收录于专栏:IMWeb前端团队IMWeb前端团队
运行总次数:0
代码可运行

上周处理了一下群活动的badjs,第一步是摆脱Script error.,捕获异常栈,找到自己是错在哪里~ 分享一下这个步骤

异步的切入点:

1、XMLHttpRequest.prototype.send

2、setTimeout、setInterval

3、define、require

4、Zepto的事件绑定 on 、bind (另外要能off、unbind)

何时引入切入文件:

最简单的方法是在requirejs引入后立刻做define,require的切入, 在Zepto加载之后做on,bind的切入。或者在zepto引入之后做所有的切入。但这样无法对inline进去的代码做切入,比如预加载的代码。既然是移动端,使用window.__defineSetter__去监听define,zepto的出现也许是最好的选择~

下面是主要的代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    _.before(XMLHttpRequest.prototype, 'send', function() {                         
        if (this.onreadystatechange) {                                              
            this.onreadystatechange = cat(this.onreadystatechange);                 
        }                                                                           
    });                                                                             

    _.before(window, 'setTimeout setInterval', catArgs);                            

    // 打包后define require有时候会被封在函数里,可以手动暴露到window上             
    _.modify(window, 'define require', funArgsFilter(catArgs));                     

    _.modify(window, 'Jquery Zepto', function($) {                                  
        if ($ && $.fn) {                                                            
            _.modify($.fn, 'on bind', funArgsFilter(catArgs));                      
            _.modify($.fn, 'off unbind', funArgsFilter(uncatArgs));                 
        }                                                                           
        return $;                                                                   
    });                                                                             

    // 手动接口                                                                     
    window.cat = cat;

需要注意:

1、对$.fn.bind做切入,一定也要对$.fn.unbind做切入,使unbind能工作

2、切入函数和被切入函数尽量保持一对一,要不然容易出现未知的问题

3、define、require在打包之后不一定会暴露到window对象上来,可以手动暴露一下

完整代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
(function() {
    var _ = {
        isFunction: function(fun) {
            return typeof fun === 'function';
        },
        // aop 注入
        before: function(obj, props, hook) {
            props.split(/\s+/).forEach(function(prop) {
                var _fun = obj[prop];
                obj[prop] = function() {
                    var args = hook.apply(this, arguments) || arguments;
                    return _fun.apply(this, args);
                };
            });
        },
        // 监听修改属性
        modify: function(obj, props, modifier) {
            if (!obj.__defineSetter__) {
                return;
            }
            props.split(/\s+/).forEach(function(prop) {
                var value = obj[prop];
                // 如果属性已经存在
                if (typeof value !== 'undefined') {
                    value = modifier.call(this, value);
                }
                obj.__defineSetter__(prop, function(_value) {
                    if (_value !== value) {
                        value = modifier.call(this, _value);
                    }
                });
                obj.__defineGetter__(prop, function() {
                    return value;
                });
            });
        }
    };


    var onthrow = function(e) {
        console.log(e);
        // TODO report
        // 设置一个标志位, window.onerror跳过这个异常,随后设为false
        window._errorthrowing = true;
        throw e;
    };


    /**
     * 包装函数
     */
    function cat(foo) {
        // 防止多次包装
        if (!_.isFunction(foo) || foo.__try) {
            return foo;
        }
        // 保持一对一,要不然容易引起未知的问题
        // 例如: 两次ele.bind('', fun)再ele.unbind('')会有一个无法unbind
        if (foo.__tryer) {
            return foo.__tryer;
        }
        var fun = function() {
            try {
                return foo.apply(this, arguments);
            } catch (e) {
                onthrow(e);
            }
        };
        foo.__tryer = fun;
        fun.__try = foo;
        fun.__proto__ = foo;
        return fun;
    }

    /**
     * 包装参数中的函数
     */
    function catArgs() {
        return [].slice.call(arguments).map(function(fun) {
            return _.isFunction(fun) ? cat(fun) : fun;
        });
    }

    /**
     * 反包装参数中的函数
     */
    function uncatArgs() {
        return [].slice.call(arguments).map(function(fun) {
            return _.isFunction(fun) && fun.__tryer ? fun.__tryer : fun;
        });
    }

    function funArgsFilter(filter) {
        return function(_fun) {
            if (!_.isFunction(_fun) || _fun.__filting) {
                return _fun;
            }
            if (_fun.__filter) {
                return _fun.__filter;
            }
            var fun = function() {
                var args = filter.apply(this, arguments);
                return _fun.apply(this, args);
            };
            _fun.__filter = fun;
            fun.__filting = _fun;
            fun.__proto__ = _fun;
            return fun;
        };
    }

    _.before(XMLHttpRequest.prototype, 'send', function() {
        if (this.onreadystatechange) {
            this.onreadystatechange = cat(this.onreadystatechange);
        }
    });

    _.before(window, 'setTimeout setInterval', catArgs);

    // 打包后define require有时候会被封在函数里,可以手动暴露到window上
    _.modify(window, 'define require', funArgsFilter(catArgs));

    _.modify(window, 'Jquery Zepto', function($) {
        if ($ && $.fn) {
            _.modify($.fn, 'on bind', funArgsFilter(catArgs));
            _.modify($.fn, 'off unbind', funArgsFilter(uncatArgs));
        }
        return $;
    });

    // 手动接口
    window.cat = cat;
})();
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
[Matlab]绘图颜色[通俗易懂]
修改或规定Matlab中几何图形的颜色,对颜色可以有四种描述方法,分别是:颜色名称、短名称、RGB三元组、十六进制颜色代码。
全栈程序员站长
2022/09/04
2K0
[Matlab]绘图颜色[通俗易懂]
matlab画点图如何设置点的大小颜色_matlab如何根据点绘制曲线图
Matlab中,plot绘图的曲线线宽、标记点大小、标记点边框颜色和填充颜色的设置
全栈程序员站长
2022/11/05
8.8K0
matlab画图操作(修改坐标轴及字体,加粗,颜色修改,适合论文画图)「建议收藏」
在我们使用imagesc()函数对矩阵进行绘制图像的时候,经常会出现y轴刻度并不是我们所需要的顺序,例如我们需要从下向上依次递增,而我们绘制的图片却是从上 向下递增,不符合我们需求,于是有如下解决方案。
全栈程序员站长
2022/11/08
15.4K0
matlab画图操作(修改坐标轴及字体,加粗,颜色修改,适合论文画图)「建议收藏」
MATLAB绘图怎么变得更好看[通俗易懂]
同样用的都是MATLAB,为啥大佬们画的图都那么好看,而你画的图都是简单、普通,那是因为我们掌握的基础元素不一样,只有掌握了最基本的基础元素,再加上日益增长的审美,才会有一张好图出来。
全栈程序员站长
2022/08/31
1.2K0
Matlab画图常用的线条符号、颜色
4 、若要同时改变颜色及图线型态(Line style),也是在坐标对后面加上相关字串即可
全栈程序员站长
2022/07/01
2.8K0
matlab二维彩图colormap调色_matlab如何自定义颜色
这个博客是自己的第一篇博客,瞎写实验中。。。 (2020年2月第一次更新,调整了一下格式,增加了常用的颜色图形式)
全栈程序员站长
2022/11/07
5.6K1
matlab二维彩图colormap调色_matlab如何自定义颜色
Matlab画图线型、符号及颜色设置
-Solid line (default) – Dashed line : Dotted line -. Dash-dot line
全栈程序员站长
2022/09/03
3.3K0
Matlab画图线型、符号及颜色设置
MATLAB绘图总结
二维图像是在不同的平面坐标上将数据点连接起来的平面图像。常用的平面坐标有,直角坐标、极坐标、对数坐标等,MATLAB有很多常用的指令来绘制不同的二维图像。
全栈程序员站长
2022/09/07
1.7K0
matlab中plotyy设置曲线颜色,matlab plotyy 颜色「建议收藏」
MATLAB 画双纵坐标 plotyy 的用法 对数坐标 MATLAB 画双纵坐标具有两个纵坐标标度的图形 在 MATLAB 中,如果需要绘制出具有不同纵坐标标度的两个图形,可以使用 ……
全栈程序员站长
2022/07/05
1.7K0
【MATLAB 从零到进阶】day6 MATLAB绘图与可视化
图形窗口、线条、曲面和注释等都被看作是MATLAB中的图形对象,所有这些图形对象都可以通过一个被称为“句柄值”的东西加以控制,例如可以通过一个线条的句柄值来修改线条的颜色、宽度和线型等属性。这里所谓的“句柄值”其实就是一个数值,每个图形对象都对应一个唯一的句柄值,它就像一个指针,与图形对象一一对应。例如可以通过命令h = figure返回一个图形窗口的句柄值。
统计学家
2019/04/10
7840
【MATLAB 从零到进阶】day6 MATLAB绘图与可视化
matlab plotyy 坐标轴设置,[转载]Matlab plotyy画双纵坐标图实例[通俗易懂]
legend([H1,H2],{‘y1 = 200*exp(-0.05*x).*sin(x)’;’y2 =
全栈程序员站长
2022/06/28
1.2K0
Matlab画图 线条的颜色、宽度等相关设置
线条的属性有:Color —— 颜色、LineWidth —— 线条宽度、LineStyle —— 线型、LineJoin —— 线条边角的样式、 AlignVertexCenters —— 锐化垂直线和水平线
全栈程序员站长
2022/09/03
14.3K0
Matlab画图 线条的颜色、宽度等相关设置
matlab内建函数怎么不同颜色,matlab分段函数不同颜色绘图
functionfunc_baidu_56568133x=-200:200;y=(x0).*(x.^2+(1-x).^(1/4)-5);figure(1);plot(x,y)fh=@func_baid
全栈程序员站长
2022/07/05
7280
matlab 画折线图并美化
ytick 和 xtick 设置x和y轴刻度线位置; 可以单独使用 xtick([1,4,7])
全栈程序员站长
2022/09/06
7500
MATLAB画图——基础篇「建议收藏」
在MATLAB使用的过程中,学会画图是一项必要的技能。在这里,我总结了部分简单的画图函数,同时附上代码(本文中的程序为了方便给出的数据都很简单,大家可以自己去尝试其他数据)。这对刚刚开始接触MATLAB的小白来说,我认为还是很有帮助的。
全栈程序员站长
2022/11/08
2.2K0
MATLAB画图——基础篇「建议收藏」
MATLAB绘制统计折线图
  在论文或者文章写作中,经常需要使用图形来表示我们的实验结果。一般来说,这种表示方式比表格更加直观、更加可视化。因此,本文给出一种使用MATLAB处理数据得到折线图的教程。
全栈程序员站长
2022/06/29
8830
MATLAB绘制统计折线图
matlab画图标签,Matlab绘图
以下示例将演示该概念。下面绘制x的值范围是从0到100,使用简单函数y = x,增量值为5。
全栈程序员站长
2022/09/12
2.4K0
matlab画图标签,Matlab绘图
数学建模之MATLAB画图汇总
1.plot()函数 plot函数用于绘制二维平面上的线性坐标曲线图,要提供一组x坐标和对应的y坐标,可以绘制分别以x和y为横、纵坐标的二维曲线。 例:
全栈程序员站长
2022/07/21
3K0
数学建模之MATLAB画图汇总
MATLAB自带的dwt2和wavedec2函数实现基于小波变换的自适应阈值图像边缘检测
小波函数有:haar小波函数、Daubechies小波函数、Biorthogo小波函数等,可以根据实际情况调用
全栈程序员站长
2022/09/15
1.9K0
MATLAB自带的dwt2和wavedec2函数实现基于小波变换的自适应阈值图像边缘检测
MATLAB plotyy总结「建议收藏」
当需要画出2个两个不同纵坐标的图时,此时的横坐标的图是相同的,在MATLAB中这个函数叫plotyy 下面列举的是一个简单的画plotyy的应用 几种不同的调用格式
全栈程序员站长
2022/07/04
5K0
MATLAB plotyy总结「建议收藏」
推荐阅读
相关推荐
[Matlab]绘图颜色[通俗易懂]
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档