首页 > 其他分享 >图片热区。vue3+ts和vue3+js写法(js没写完数据,功能完善)2

图片热区。vue3+ts和vue3+js写法(js没写完数据,功能完善)2

时间:2024-08-19 18:06:41浏览次数:8  
标签:end list hot value js start drag vue3 功能完善

不知道为啥我上一篇的图片热区被移出首页,其实我主要是是为了自己看,其次才是分享,这段时间我又整理了一下热区,将里面的功能进一步完善了一下;

解决一下问题:

1.解决拖拽到规定区域外后松开鼠标再次进入后,坐标错误的问题

2.新增6个方向的拖拽放大缩小热区区域

3.新增放大了图片区域

4.做了相对于屏幕大小进行的百分比定位,解决因屏幕大小导致的定位错误问题

5.新增了新增热区功能,可手动点击按钮生成热区

6.解决了热区贴边不准确的问题

<!-- 上传组件 -->
<template>
    <el-dialog v-model="dialog_visible" fullscreen @close="close_event">
        <template #header>
            <div class="title re">
                <div class="tc size-16 fw">编辑热区</div>
            </div>
        </template>
        <el-scrollbar class="content-scrollbar">
            <div class="pa-40 flex-row gap-40">
                <div class="left-content flex-1 pa-20">
                    <el-scrollbar class="img-scrollbar">
                        <div class="img-container">
                            <div class="re">
                                <div ref="imgBoxRef" class="oh" @mousedown.prevent="start_drag" @mousemove.prevent="move_drag" @mouseup.prevent="end_drag">
                                    <div ref="imgRef">
                                        <el-image :src="hot_list.img" class="w img block" @selectstart.prevent @contextmenu.prevent @dragstart.prevent></el-image>
                                    </div>
                                    <div ref="areaRef" class="area" :style="init_drag_style"></div>
                                    <div v-for="(item, index) in hot_list.data" :key="index" class="area-box" :style="rect_style(item.drag_start, item.drag_end)" @mousedown.stop="start_drag_area_box(index, $event)" @dblclick="dbl_drag_event(item, index)">
                                        <div class="del-btn" @click.stop="del_area_event(index)"><icon name="close"></icon></div>
                                        <div class="drag-btn drag-tl" :data-index="index" @mousedown.stop="start_drag_btn_tl(index, $event)"></div>
                                        <div class="drag-btn drag-tc" :data-index="index" @mousedown.stop="start_drag_btn_tc(index, $event)"></div>
                                        <div class="drag-btn drag-lc" :data-index="index" @mousedown.stop="start_drag_btn_lc(index, $event)"></div>
                                        <div class="drag-btn drag-bl" :data-index="index" @mousedown.stop="start_drag_btn_bl(index, $event)"></div>
                                        <div class="drag-btn drag-bc" :data-index="index" @mousedown.stop="start_drag_btn_bc(index, $event)"></div>
                                        <!-- 已完成 -->
                                        <div class="drag-btn drag-br" :data-index="index" @mousedown.stop="start_drag_btn_br(index, $event)"></div>
                                        <div class="drag-btn drag-rc" :data-index="index" @mousedown.stop="start_drag_btn_rc(index, $event)"></div>
                                        <div class="text">
                                            <div class="name">{{ item.name }}</div>
                                            <div class="status" :class="!is_obj_empty(item.link) ? 'cr-primary' : 'cr-error'">{{ !is_obj_empty(item.link) ? (item.link?.name ?? '未设置') : '未设置' }}</div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        </div>
                    </el-scrollbar>
                </div>
                <div class="right-content flex-1 pa-20">
                    <div class="size-16 fw mb-10">图片热区</div>
                    <div class="flex-col gap-20 item">
                        <div v-for="(item, index) in hot_list.data" :key="index" class="flex-row align-c gap-10">
                            <el-input v-model="item.name" class="name" placeholder="名称"></el-input>
                            <url-value v-model="item.link"></url-value>
                            <icon name="del" size="20" @click="del_event(index)"></icon>
                        </div>
                        <el-button type="primary" class="add_hot" @click="add_event">添加选区</el-button>
                        <div class="size-12 cr-9">框选热区范围,双击设置热区信息</div>
                    </div>
                </div>
            </div>
        </el-scrollbar>
        <template #footer>
            <span class="dialog-footer">
                <el-button class="plr-28 ptb-10" type="primary" @click="confirm_event">完成</el-button>
            </span>
        </template>
    </el-dialog>
    <el-dialog v-model="hot_dialog_visible" width="560" append-to-body draggable @close="hot_close_event">
        <template #header>
            <div class="title re">
                <div class="tc size-16 fw">设置热区</div>
            </div>
        </template>
        <div class="content">
            <el-form ref="formRef" :model="form" label-width="85px" class="pa-20 mt-16">
                <el-form-item label="名称">
                    <el-input v-model="form.name" placeholder="请输入名称"></el-input>
                </el-form-item>
                <el-form-item label="热区跳转链接">
                    <url-value v-model="form.link"></url-value>
                </el-form-item>
            </el-form>
        </div>
        <template #footer>
            <span class="dialog-footer">
                <el-button class="plr-28 ptb-10" @click="hot_close_event">取消</el-button>
                <el-button class="plr-28 ptb-10" type="primary" @click="hot_confirm_event">确定</el-button>
            </span>
        </template>
    </el-dialog>
    <el-button class="w" @click="open_hot_event"><icon name="add">编辑热区</icon></el-button>
</template>
<script lang="ts" setup>
import { cloneDeep } from 'lodash';
import { is_obj_empty } from '@/utils';
const app = getCurrentInstance();
/**
 * @description: 热区
 * @param modelValue{Object} 默认值
 * @param dialog_visible {Boolean} 弹窗显示
 * @return {*} update:modelValue
 */
const props = defineProps({});
const modelValue = defineModel({ type: Object as PropType<hotData>, default: {} });
const dialog_visible = defineModel('visibleDialog', { type: Boolean, default: false });

const hot_list = ref<hotData>({
    img: '',
    img_height: 1,
    img_width: 1,
    data: [],
});
const hot_list_index = ref(0);

//#region 左侧画布-----------------------------------------------start
const imgBoxRef = ref<HTMLElement | null>(null);
const imgRef = ref<HTMLElement | null>(null);
const rect_start = ref<rectCoords>({ x: 0, y: 0, width: 0, height: 0 });
const rect_end = ref<rectCoords>({ x: 0, y: 0, width: 0, height: 0 });
const areaRef = ref<HTMLElement | null>(null);
const init_drag_style = ref('');
// 拖拽生成盒子的开关
const drag_bool = ref(false);
// 拖拽盒子的开关
const drag_box_bool = ref(false);
// 拖拽放大缩小盒子的开关
const drag_box_scale_bool = ref(false);
const start_drag = (event: MouseEvent) => {
    drag_bool.value = true;
    if (!imgBoxRef.value) return;
    rect_start.value.x = rect_start.value.x !== 0 ? rect_start.value.x : event.clientX - imgBoxRef.value.getBoundingClientRect().left;
    rect_start.value.y = rect_start.value.y !== 0 ? rect_start.value.y : event.clientY - imgBoxRef.value.getBoundingClientRect().top;
    rect_start.value.width = 0;
    rect_start.value.height = 0;
};
const move_drag = (event: MouseEvent) => {
    if (drag_bool.value) {
        if (!imgBoxRef.value) return;
        rect_end.value.x = event.clientX - imgBoxRef.value.getBoundingClientRect().left;
        rect_end.value.y = event.clientY - imgBoxRef.value.getBoundingClientRect().top;
        rect_end.value.width = rect_end.value.x - rect_start.value.x > 0 ? rect_end.value.x - rect_start.value.x : 0;
        rect_end.value.height = rect_end.value.y - rect_start.value.y > 0 ? rect_end.value.y - rect_start.value.y : 0;
        init_drag_style.value = `left: ${rect_start.value.x}px;top: ${rect_start.value.y}px;width: ${Math.max(rect_end.value.width, 1)}px;height: ${Math.max(rect_end.value.height, 1)}px;display: flex;`;
    }
};
const end_drag = (event: MouseEvent) => {
    drag_bool.value = false;
    if (areaRef.value) areaRef.value.style.display = 'none';
    if (!imgBoxRef.value) return;
    init_drag_style.value = ``;
    if (rect_end.value.width > 16 && rect_end.value.height > 16) {
        hot_list.value.data.push({
            name: '热区' + (hot_list.value.data.length + 1),
            link: {},
            drag_start: cloneDeep(rect_start.value),
            drag_end: cloneDeep(rect_end.value),
        });
    }
    rect_start.value = { x: 0, y: 0, width: 0, height: 0 };
    rect_end.value = { x: 0, y: 0, width: 0, height: 0 };
};

const area_box_point = ref({ x: 0, y: 0 });
// area-box
const dbl_drag_event = (item: hotListData, index: number) => {
    hot_dialog_visible.value = true;
    form.value.link = item.link;
    form.value.name = item.name;
    hot_list_index.value = index;
};
const start_drag_area_box = (index: number, event: MouseEvent) => {
    hot_list_index.value = index;
    event.stopPropagation();
    drag_box_bool.value = true;
    let clone_drag_start = cloneDeep(hot_list.value.data[hot_list_index.value].drag_start);
    let clone_drag_end = cloneDeep(hot_list.value.data[hot_list_index.value].drag_end);
    // 记录原始位置
    area_box_point.value = {
        x: clone_drag_start.x - event.clientX,
        y: clone_drag_start.y - event.clientY,
    };

    // 当子元素拖拽方法触发后父元素方法不触发
    document.onmousemove = (areaBoxEvent) => {
        // areaBoxEvent.stopPropagation();
        if (drag_box_bool.value) {
            if (!imgBoxRef.value) return;
            const new_coordinate = {
                x: areaBoxEvent.clientX + area_box_point.value.x,
                y: areaBoxEvent.clientY + area_box_point.value.y,
            };
            // 左上边界判断
            if (new_coordinate.x < 0) {
                new_coordinate.x = 0;
            }
            if (new_coordinate.y < 0) {
                new_coordinate.y = 0;
            }
            // 右下边界判断
            if (new_coordinate.x + Math.max(clone_drag_end.width, 1) > imgBoxRef.value.getBoundingClientRect().width) {
                new_coordinate.x = imgBoxRef.value.getBoundingClientRect().width - Math.max(clone_drag_end.width, 1);
            }
            if (new_coordinate.y + Math.max(clone_drag_end.height, 1) > imgBoxRef.value.getBoundingClientRect().height) {
                new_coordinate.y = imgBoxRef.value.getBoundingClientRect().height - Math.max(clone_drag_end.height, 1);
            }
            hot_list.value.data[hot_list_index.value].drag_start.x = new_coordinate.x;
            hot_list.value.data[hot_list_index.value].drag_start.y = new_coordinate.y;
            hot_list.value.data[hot_list_index.value].drag_end.x = new_coordinate.x + Math.max(clone_drag_end.width, 1);
            hot_list.value.data[hot_list_index.value].drag_end.y = new_coordinate.y + Math.max(clone_drag_end.height, 1);
        }
    };
    document.onmouseup = (areaBoxEvent) => {
        // areaBoxEvent.stopPropagation();
        drag_box_bool.value = false;
    };
};
// drag-btn
const start_drag_btn_br = (index: number, event: MouseEvent) => {
    start_drag_btn(index, event, 'br');
};
const start_drag_btn_bl = (index: number, event: MouseEvent) => {
    start_drag_btn(index, event, 'bl');
};
const start_drag_btn_bc = (index: number, event: MouseEvent) => {
    start_drag_btn(index, event, 'bc');
};
const start_drag_btn_tl = (index: number, event: MouseEvent) => {
    start_drag_btn(index, event, 'tl');
};
const start_drag_btn_tc = (index: number, event: MouseEvent) => {
    start_drag_btn(index, event, 'tc');
};
const start_drag_btn_lc = (index: number, event: MouseEvent) => {
    start_drag_btn(index, event, 'lc');
};
const start_drag_btn_rc = (index: number, event: MouseEvent) => {
    start_drag_btn(index, event, 'rc');
};
// 画布拖拽公用方法
const start_drag_btn = (index: number, event: MouseEvent, type: string) => {
    hot_list_index.value = index;
    event.stopPropagation();
    drag_box_scale_bool.value = true;
    let clone_drag_start = hot_list.value.data[hot_list_index.value].drag_start;
    let clone_drag_end = hot_list.value.data[hot_list_index.value].drag_end;
    document.onmousemove = (dragBtnEvent) => {
        // dragBtnEvent.stopPropagation();
        //用鼠标的位置减去鼠标相对元素的位置,得到元素的位置
        if (drag_box_scale_bool.value) {
            if (!imgBoxRef.value) return;

            switch (type) {
                case 'br':
                    // 下右
                    clone_drag_end.x = handleBoundary(dragBtnEvent.clientX - imgBoxRef.value.getBoundingClientRect().left, 0, imgBoxRef.value.getBoundingClientRect().width);
                    clone_drag_end.y = handleBoundary(dragBtnEvent.clientY - imgBoxRef.value.getBoundingClientRect().top, 0, imgBoxRef.value.getBoundingClientRect().height);
                    hot_list.value.data[hot_list_index.value].drag_end = updateDragEnd(clone_drag_start, clone_drag_end, clone_drag_end);
                    break;
                case 'bl':
                    // 下左
                    clone_drag_start.x = handleBoundary(dragBtnEvent.clientX - imgBoxRef.value.getBoundingClientRect().left, 0, clone_drag_end.x);
                    clone_drag_end.y = handleBoundary(dragBtnEvent.clientY - imgBoxRef.value.getBoundingClientRect().top, 0, imgBoxRef.value.getBoundingClientRect().height);
                    hot_list.value.data[hot_list_index.value].drag_start.x = clone_drag_start.x;
                    hot_list.value.data[hot_list_index.value].drag_end.y = clone_drag_end.y;
                    hot_list.value.data[hot_list_index.value].drag_end = updateDragEnd(clone_drag_start, clone_drag_end, { y: clone_drag_end.y });
                    break;
                case 'bc':
                    // 下中
                    clone_drag_end.y = handleBoundary(dragBtnEvent.clientY - imgBoxRef.value.getBoundingClientRect().top, 0, imgBoxRef.value.getBoundingClientRect().height);
                    hot_list.value.data[hot_list_index.value].drag_end.y = clone_drag_end.y;
                    hot_list.value.data[hot_list_index.value].drag_end = updateDragEnd(clone_drag_start, clone_drag_end, { y: clone_drag_end.y });
                    break;
                case 'tl':
                    // 上左
                    clone_drag_start.x = handleBoundary(dragBtnEvent.clientX - imgBoxRef.value.getBoundingClientRect().left, 0, clone_drag_end.x);
                    clone_drag_start.y = handleBoundary(dragBtnEvent.clientY - imgBoxRef.value.getBoundingClientRect().top, 0, clone_drag_end.y);
                    hot_list.value.data[hot_list_index.value].drag_start.x = clone_drag_start.x;
                    hot_list.value.data[hot_list_index.value].drag_start.y = clone_drag_start.y;
                    hot_list.value.data[hot_list_index.value].drag_end = updateDragEnd(clone_drag_start, clone_drag_end, {});
                    break;
                case 'tc':
                    // 上中
                    clone_drag_start.y = handleBoundary(dragBtnEvent.clientY - imgBoxRef.value.getBoundingClientRect().top, 0, clone_drag_end.y);
                    hot_list.value.data[hot_list_index.value].drag_start.y = clone_drag_start.y;
                    hot_list.value.data[hot_list_index.value].drag_end = updateDragEnd(clone_drag_start, clone_drag_end, { y: clone_drag_end.y });
                    break;
                case 'lc':
                    // 左中
                    clone_drag_start.x = handleBoundary(dragBtnEvent.clientX - imgBoxRef.value.getBoundingClientRect().left, 0, clone_drag_end.x);
                    hot_list.value.data[hot_list_index.value].drag_start.x = clone_drag_start.x;
                    hot_list.value.data[hot_list_index.value].drag_end = updateDragEnd(clone_drag_start, clone_drag_end, {});
                    break;
                case 'rc':
                    // 右中
                    clone_drag_end.x = handleBoundary(dragBtnEvent.clientX - imgBoxRef.value.getBoundingClientRect().left, 0, imgBoxRef.value.getBoundingClientRect().width);
                    hot_list.value.data[hot_list_index.value].drag_end.x = clone_drag_end.x;
                    hot_list.value.data[hot_list_index.value].drag_end = updateDragEnd(clone_drag_start, clone_drag_end, { x: clone_drag_end.x });
                    break;
            }
        }
    };
    document.onmouseup = (dragBtnEvent2) => {
        // dragBtnEvent2.stopPropagation();
        drag_box_scale_bool.value = false;
    };
};

// 辅助函数用于更新drag_end
const updateDragEnd = (dragStart: { x: number; y: number }, dragEnd: { x: number; y: number }, newDragEnd: { x?: number; y?: number }) => {
    const newX = newDragEnd.x !== undefined ? newDragEnd.x : dragEnd.x;
    const newY = newDragEnd.y !== undefined ? newDragEnd.y : dragEnd.y;
    return {
        x: newX,
        y: newY,
        width: newX - dragStart.x > 0 ? newX - dragStart.x : 0,
        height: newY - dragStart.y > 0 ? newY - dragStart.y : 0,
    };
};

// 辅助函数用于更新drag_start
const updateDragStart = (dragStart: { x: number; y: number }, newDragStart: { x?: number; y?: number }) => {
    const newX = newDragStart.x !== undefined ? newDragStart.x : dragStart.x;
    const newY = newDragStart.y !== undefined ? newDragStart.y : dragStart.y;
    return { x: newX, y: newY };
};

// 辅助函数用于处理边界
const handleBoundary = (value: number, min: number, max: number) => Math.max(min, Math.min(value, max));

const del_area_event = (index: number) => {
    hot_list.value.data.splice(index, 1);
};
const rect_style = computed(() => {
    return (start: rectCoords, end: rectCoords) => {
        return `left: ${start.x}px;top: ${start.y}px;width: ${Math.max(end.width, 1)}px;height: ${Math.max(end.height, 1)}px;display: flex;`;
    };
});

//#endregion 左侧画布-----------------------------------------------end

//#region 右侧热区编辑-----------------------------------------------start
const del_event = (index: number) => {
    hot_list.value.data.splice(index, 1);
};
const add_event = () => {
    hot_list.value.data.push({
        name: '热区' + (hot_list.value.data.length + 1),
        link: {},
        drag_start: {
            x: 0,
            y: 0,
            width: 0,
            height: 0,
        },
        drag_end: {
            x: 100,
            y: 100,
            width: 100,
            height: 100,
        },
    });
};
//#endregion 右侧热区编辑-----------------------------------------------end

//#region 设置热区弹窗-----------------------------------------------start
const hot_dialog_visible = ref(false);
interface formData {
    link: linkData;
    name: string;
}
const form = ref<formData>({
    link: {
        name: '',
    },
    name: '',
});
const hot_close_event = () => {
    hot_dialog_visible.value = false;
};
const hot_confirm_event = () => {
    hot_list.value.data[hot_list_index.value].name = form.value.name;
    if (hot_list.value.data[hot_list_index.value].link) {
        hot_list.value.data[hot_list_index.value].link = form.value.link;
    }
    hot_close_event();
};
//#endregion 设置热区弹窗-----------------------------------------------end

//#region 热区开启关闭确认取消回调 -----------------------------------------------start
// 打开热区弹窗
const open_hot_event = () => {
    if (modelValue.value.img.length > 0) {
        dialog_visible.value = true;
        hot_list.value.img = modelValue.value.img;
        setTimeout(() => {
            // 创建临时变量储存传过来的数据
            let temp_data = cloneDeep(modelValue.value);
            // 获取最新的图片高度和宽度
            temp_data.img_height = imgBoxRef.value?.clientHeight || 0;
            temp_data.img_width = imgBoxRef.value?.clientWidth || 0;
            // 根据原始数据的宽高和更新后的宽高的比例,计算出事实的坐标比例
            const scale = temp_data.img_width / modelValue.value.img_width;
            console.log(scale);
            temp_data.data.forEach((item) => {
                item.drag_start.x = item.drag_start.x * scale;
                item.drag_start.y = item.drag_start.y * scale;
                item.drag_end.x = item.drag_end.x * scale;
                item.drag_end.y = item.drag_end.y * scale;
                item.drag_end.width = item.drag_end.width * scale;
                item.drag_end.height = item.drag_end.height * scale;
            });
            hot_list.value = temp_data;
        }, 100);
    } else {
        ElMessage({
            type: 'warning',
            message: '请先选择图片',
        });
    }
};

// 取消回调
const close_event = () => {
    dialog_visible.value = false;
};
// 确认回调
const confirm_event = () => {
    if (hot_list.value.data.length > 0) {
        // 筛选数组hot中所有的link是否有空值,如果有则提示出来
        if (is_obj_empty(hot_list.value.data)) {
            ElMessage({
                type: 'warning',
                message: '请先设置热区',
            });
            return;
        }
        const no_link_list = hot_list.value.data.filter((item) => {
            return is_obj_empty(item.link);
        });
        if (no_link_list.length > 0) {
            ElMessage.error('请设置热区链接!');
            return;
        } else {
            modelValue.value = cloneDeep(hot_list.value);
            close_event();
        }
    } else {
        ElMessage.error('至少选择一个热区!');
    }
};
//#endregion 热区开启关闭确认取消回调 -----------------------------------------------end
</script>
<style lang="scss" scoped>
@import 'index.scss';
</style>

 

标签:end,list,hot,value,js,start,drag,vue3,功能完善
From: https://www.cnblogs.com/sws-kevin/p/18367830

相关文章

  • vue3 之 多张图片压缩下载
    一、涉及的插件①JSZip:jszip是一个用于创建、读取和编辑.zip文件的JavaScript库② FileSaver:FileSaver是一个用于在客户端保存文件的JavaScript库。它提供了一种简单的方式来将数据保存为本地文件,通常用于在浏览器中将动态生成的内容(如图像、文档、压缩文件等)保存......
  • 解决Vue3+Ts打包项目时会生成很多的map文件
     正常打包会生成.js和.map文件怎么去解决它呢?正常来说我们会在vite.config.ts配置我们的项目打包方式,如下:(我这里的target:es2022是为了支持模块中顶层await的使用)//Vite配置文件exportdefault{build:{//指定构建输出目录outDir:"dist",//使用"......
  • Visual Studio 2013 jsoncpp 0.10.7库编译
    前言全局说明VisualStudio2013jsoncpp编译jsoncpp介绍说明:https://www.cnblogs.com/wutou/p/18367551一、说明环境:Windows7旗舰版VisualStudio2013二、选择根据vs2013工具环境和jsoncpp介绍,这里选用0.10.7版本演示三、准备3.1解压文件进入m......
  • html JS 语音识别
    1、语音识别的过程语音识别涉及三个过程:首先,需要设备的麦克风接收这段语音;其次,语音识别服务器会根据一系列语法(基本上,语法是你希望在具体的应用中能够识别出来的词汇)来检查这段语音;最后,当一个单词或者短语被成功识别后,结果会以文本字符串的形式返回(结果可以有多个),以及更多......
  • jsoncpp 介绍
    前言全局说明VisualStudio2013jsoncpp编译一、说明环境:Windows7旗舰版VisualStudio2013二、常用的JSON解析库有:(ChatGPT)nlohmann/json(一个现代C++JSON库)https://github.com/nlohmann/json/releasesJsonCpp(一个常见的JSON解析库)https://github.com......
  • el-table使用sortablejs推拽排序卡顿问题解决
    使用sortablejs拖拽el-table排序时,对于纯文本表格,正常使用即可,不会卡顿initSort(){consttbody=document.querySelector('.el-table__body-wrappertbody')const_this=thisSortable.create(tbody,{draggable:'.el-table__row',......
  • MySQL中处理JSON数据:大数据分析的新方向
    1.简介1.1.概述在MySQL中处理JSON数据的能力是在MySQL5.7版本中引入的,并在后续的版本中不断得到增强。这使得MySQL能够直接操作和查询JSON格式的数据,极大地扩展了其处理复杂数据结构的能力。1.2.主要特点灵活性与可扩展性:JSON允许开发者存储不规则和嵌套的数据结......
  • ZoneJs 源码解析
    ZoneJs源码解析ZoneJs是什么,它能干什么,它是怎么做到的?Zone是为js的执行提供了一个共享的数据上下文。为js函数执行维护了一个逻辑上的调用栈。同时提供了对于函数执行方法的拦截,在函数执行前后,添加一些通用的逻辑(例如日志,异常处理)。统一的任务模型,提供对于宏任务/微任务/......
  • 上传图片js
    <html><body><scriptsrc="http://apps.bdimg.com/libs/jquery/2.1.4/jquery.min.js"></script><script>functionchangImg(e){for(vari=0;i<e.target.files.length;i++){......
  • FastJson引入存在DDos攻击安全漏洞案例分析
    FastJson引入存在DDos攻击安全漏洞案例分析背景   某集团公司门户网站接口存在DDos攻击安全漏洞,其他服务端工程中依赖Fastjson进行序列化。Fastjson是阿里巴巴开发的一款高性能的JavaJSON处理库。本身在处理JSON数据时可能存在安全性问题,如JSON注入攻击。DDoS攻击是指攻击者......