Vue2 _ 实现拖拽功能

article/2025/9/14 4:57:24

老项目重构,其中有一些拖拽功能,不过用的是两个开源 JS 拖拽文件实现的效果,版本太老了,所以需要换代了,然后就查阅了能够用 Vue 来简单快速实现拖拽的功能实现方法 :

目录

一、HTML 拖放

二、Vue.Draggable ( 强烈推荐 )

三、vue-grid-layout


一、HTML 拖放

首先我们可以使用 HTML 5 本身自带的 拖放 功能 :

官方文档 :  HTML5 拖放

HTML 拖放实例

下列是关于拖放的简单例子:

 实例 :

<!DOCTYPE HTML>
<html>
<head>
<script>
function allowDrop(ev) {ev.preventDefault();
}function drag(ev) {ev.dataTransfer.setData("text", ev.target.id);
}function drop(ev) {ev.preventDefault();var data = ev.dataTransfer.getData("text");ev.target.appendChild(document.getElementById(data));
}
</script>
</head>
<body><div id="div1" ondrop="drop(event)" ondragover="allowDrop(event)"></div><img id="drag1" src="img_logo.gif" draggable="true" ondragstart="drag(event)" width="336" height="69"></body>
</html>

它也许看上去有点复杂,不过让我们研究一下拖放事件的所有不同部分。


把元素设置为可拖放

首先:为了把一个元素设置为可拖放,请把 draggable 属性设置为 true:

<img draggable="true">

拖放的内容 - ondragstart 和 setData()

然后,规定当元素被拖动时发生的事情。

在上面的例子中,ondragstart 属性调用了一个 drag(event) 函数,规定拖动什么数据。

dataTransfer.setData() 方法设置被拖动数据的数据类型和值:

function drag(ev) {ev.dataTransfer.setData("text", ev.target.id);
}

在本例中,数据类型是 "text",而值是这个可拖动元素的 id ("drag1")。


拖到何处 - ondragover

ondragover 事件规定被拖动的数据能够被放置到何处。

默认地,数据/元素无法被放置到其他元素中。为了实现拖放,我们必须阻止元素的这种默认的处理方式。

这个任务由 ondragover 事件的 event.preventDefault() 方法完成:

event.preventDefault()

进行放置 - ondrop

当放开被拖数据时,会发生 drop 事件。

在上面的例子中,ondrop 属性调用了一个函数,drop(event):

function drop(ev) {ev.preventDefault();var data = ev.dataTransfer.getData("text");ev.target.appendChild(document.getElementById(data));
}

代码解释:

  • 调用 preventDefault() 来阻止数据的浏览器默认处理方式( drop 事件的默认行为是以链接形式打开)
  • 通过 dataTransfer.getData() 方法获得被拖的数据。该方法将返回在 setData() 方法中设置为相同类型的任何数据
  • 被拖数据是被拖元素的 id ("drag1")
  • 把被拖元素追加到放置元素中

二、Vue.Draggable ( 强烈推荐 )

查阅各类网站文档后,决定试一下 Vue.Draggable

vue.draggable中文文档 :

vue.draggable中文文档 - itxst.com

Vue.Draggable 是一款基于 Sortable.js 实现的 Vue 拖拽插件。支持移动设备、拖拽和选择文本、智能滚动,可以在不同列表间拖拽、不依赖 jQuery 为基础、Vue 2 过渡动画兼容、支持撤销操作。

1.在项目中总会遇见一些需要排序的数据 , 我们可以通过 vue.draggable 进行拖动排序 。
2.Draggable 为基于 Sortable.js 的 vue 组件,用以实现拖拽功能。
3.拖顶的数据和 data 里的数据为双向绑定 ,在界面变的时候 data 中的数据也在跟着变化。

安装

npm i -S vuedraggable

使用

页面引入

import draggable from "vuedraggable"

定义组件

  components: {draggable},

定义参数 

data() {return {drag: false,syllable: [{title: '第 1 组'},{title: '第 2 组'},{title: '第 3 组'},]}
}

页面使用

  <draggableclass="syllable_ul"element="ul":list="syllable":options="{group:'title', animation:150}":no-transition-on-drag="true"@change="change"@start="start"@end="end":move="move"><transition-group type="transition"  :name="!drag? 'syll_li' : null" :css="true"><li v-for="(item , idx) in syllable" :key="idx">{{item.title}}</li></transition-group></draggable>

事件

// evt 里面有两个值,一个 evt.added 和 evt.removed
// 可以分别知道移动元素的 ID 和 删除元素的 IDchange(evt) {console.log(evt , 'change...')},// start , end , add , update , sort , remove 得到的都差不多start(evt) {this.drag = trueconsole.log(evt , 'start...')},end(evt) {console.log(evt , 'end....')this.drag = trueevt.item  // 可以知道拖动的本身evt.to    // 可以知道拖动的目标列表evt.from  // 可以知道之前的列表evt.oldIndex  // 可以知道拖动前的位置evt.newIndex  // 可以知道拖动后的位置},move(evt, originalEvent) {console.log(evt , 'move')console.log(originalEvent) // 鼠标位置}

文章 强烈 推荐  =>

记录Vue.Draggable拖拽组件的使用历程

https://blog.csdn.net/weixin_58099 


三、vue-grid-layout

( 二 )最近在完成 web 端在线绘图功能时,需要开发一个从左侧拖拽一种图标到画布中。调研了非常多种现在做拖拽布局的组件,调研的地址是:

Drag - Vue.js Examples

经过比较,选择了一款优秀的可拖拽框架,vue-grid-layout 。

npm 安装

npm install vue-grid-layout --save

使用 demo

    <grid-layout:layout.sync="layout":col-num="12":row-height="30":is-draggable="true":is-resizable="true":is-mirrored="false":vertical-compact="true":margin="[10, 10]":use-css-transforms="true"><grid-item v-for="item in layout":x="item.x":y="item.y":w="item.w":h="item.h":i="item.i":key="item.i">{{item.i}}</grid-item></grid-layout>
data() {return {layout: [{"x":0,"y":0,"w":2,"h":2,"i":"0"},{"x":2,"y":0,"w":2,"h":4,"i":"1"},{"x":4,"y":0,"w":2,"h":5,"i":"2"},{"x":6,"y":0,"w":2,"h":3,"i":"3"},{"x":8,"y":0,"w":2,"h":3,"i":"4"},{"x":10,"y":0,"w":2,"h":3,"i":"5"},{"x":0,"y":5,"w":2,"h":5,"i":"6"},{"x":2,"y":5,"w":2,"h":5,"i":"7"},{"x":4,"y":5,"w":2,"h":5,"i":"8"},{"x":6,"y":3,"w":2,"h":4,"i":"9"},{"x":8,"y":4,"w":2,"h":4,"i":"10"},{"x":10,"y":4,"w":2,"h":4,"i":"11"},{"x":0,"y":10,"w":2,"h":5,"i":"12"},{"x":2,"y":10,"w":2,"h":5,"i":"13"},{"x":4,"y":8,"w":2,"h":4,"i":"14"},{"x":6,"y":8,"w":2,"h":4,"i":"15"},{"x":8,"y":10,"w":2,"h":5,"i":"16"},{"x":10,"y":4,"w":2,"h":2,"i":"17"},{"x":0,"y":9,"w":2,"h":3,"i":"18"},{"x":2,"y":6,"w":2,"h":2,"i":"19"}];}
}

文档

属性参数说明

GridLayout

  • layout

    • type: Array
    • required: true

    数据源。值必须为 Array,其数据项为 Object。 每条数据项必须有 ixyw 和 h 属性。 请参考下面的 GridItem

  • responsiveLayouts

    • type: Object
    • required: false
    • default: {}

    如果 responsive 设置为 true,该配置将作为栅格中每个断点的初始布局。键值是断点名称,每项的值都是类似 layout 属性定义的数据结构,值必须为 Array,其数据项为 Object。例如: {lg: [layout items], md: [layout items]}。需要注意的是,在创建栅格布局后设置该属性无效。

  • colNum

    • type: Number
    • required: false
    • default: 12

    定义栅格系统的列数,其值需为自然数。

  • rowHeight

    • type: Number
    • required: false
    • default: 150

    每行的高度,单位像素。

  • maxRows

    • type: Number
    • required: false
    • default: Infinity

    定义最大行数。

  • margin

    • type: Array
    • required: false
    • default: [10, 10]

    定义栅格中的元素边距。

    值必须是包含两个 Number的数组,数组中第一个元素表示水平边距,第二个表示垂直边距,单位为像素。

  • isDraggable

    • type: Boolean
    • required: false
    • default: true

    标识栅格中的元素是否可拖拽。

  • isResizable

    • type: Boolean
    • required: false
    • default: true

    标识栅格中的元素是否可调整大小。

  • isMirrored

    • type: Boolean
    • required: false
    • default: false

    标识栅格中的元素是否可镜像反转。

  • autoSize

    • type: Boolean
    • required: false
    • default: true

    标识容器是否自动调整大小。

  • verticalCompact

    • type: Boolean
    • required: false
    • default: true

    标识布局是否垂直压缩。

  • useCssTransforms

    • type: Boolean
    • required: false
    • default: true

    标识是否使用CSS属性 transition-property: transform;

  • responsive

    • type: Boolean
    • required: false
    • default: false

    标识布局是否为响应式。

  • breakpoints

    • type: Object
    • required: false
    • default: { lg: 1200, md: 996, sm: 768, xs: 480, xxs: 0 }

    为响应式布局设置断点,其中参数代表不同设备的宽度:lg(large),md(medium),sm(small),xs(extra small)。

  • cols

    • type: Object
    • required: false
    • default: { lg: 12, md: 10, sm: 6, xs: 4, xxs: 2 }

    设置每个断点对应的列数。

  • useStyleCursor

    • type: Boolean
    • required: false
    • default: true

    标识是否使用动态鼠标指针样式。当拖动出现卡顿时,将此值设为 false也许可以缓解布局问题。

  • preventCollision

    • type: Boolean
    • default: false

    值设置为ture时,栅格只能拖动至空白处。

GridItem

  • i

    • type: String
    • required: true

    栅格中元素的ID。

  • x

    • type: Number
    • required: true

    标识栅格元素位于第几列,需为自然数。

  • y

    • type: Number
    • required: true

    标识栅格元素位于第几行,需为自然数。

  • w

    • type: Number
    • required: true

    标识栅格元素的初始宽度,值为colWidth的倍数。

  • h

    • type: Number
    • required: true

    标识栅格元素的初始高度,值为rowHeight的倍数。

  • minW

    • type: Number
    • required: false
    • default: 1

    栅格元素的最小宽度,值为colWidth的倍数。

    如果w小于minW,则minW的值会被w覆盖。

  • minH

    • type: Number
    • required: false
    • default: 1

    栅格元素的最小高度,值为rowHeight的倍数。

    如果h小于minH,则minH的值会被h覆盖。

  • maxW

    • type: Number
    • required: false
    • default: Infinity

    栅格元素的最大宽度,值为colWidth的倍数。

    如果w大于maxW,则maxW的值会被w覆盖。

  • maxH

    • type: Number
    • required: false
    • default: Infinity

    栅格元素的最大高度,值为rowHeight的倍数。

    如果h大于maxH,则maxH的值会被h覆盖。

  • isDraggable

    • type: Boolean
    • required: false
    • default: null

    标识栅格元素是否可拖拽。如果值为null则取决于父容器。

  • isResizable

    • type: Boolean
    • required: false
    • default: null

    标识栅格元素是否可调整大小。如果值为null则取决于父容器。

  • static

    • type: Boolean
    • required: false
    • default: false

    标识栅格元素是否为静态的(无法拖拽、调整大小或被其他元素移动)。

  • dragIgnoreFrom

    • type: String
    • required: false
    • default: 'a, button'

    标识栅格元素中哪些子元素无法触发拖拽事件,值为css-like选择器。

    请参考 interact.js docs中的ignoreFrom

  • dragAllowFrom

    • type: String
    • required: false
    • default: null

    标识栅格元素中哪些子元素可以触发拖拽事件,值为css-like选择器。

    如果值为null则表示所有子元素(dragIgnoreFrom的除外)。

    请参考 interact.js docs中的allowFrom

  • resizeIgnoreFrom

    • type: String
    • required: false
    • default: 'a, button'

    标识栅格元素中哪些子元素无法触发调整大小的事件,值为css-like选择器。

    请参考 interact.js docs中的ignoreFrom


限制可拖拽区域

如果我们希望可拖拽的组件中,内部是可以单独点击的,那么需要就拖拽的区域分隔。这里官方提供了参数,可以指定哪些区域是可以拖拽的,哪些区域会被忽略,从而被忽略的区域可以单独进行点击。

 <grid-item v-for="item in layout":x="item.x":y="item.y":w="item.w":h="item.h":i="item.i"drag-allow-from=".vue-draggable-handle"drag-ignore-from=".no-drag"><div class="text"><div class="vue-draggable-handle"></div><div class="no-drag"><span>{{item.i}}</span><br/><button>click</button></div></div></grid-item>


从外部拖拽组件到画布中

在我们的应用中希望,组件能够从左侧拖到画布中,而再进行拖拽,所以我们在右侧需要先写一个区域是用来被拖拽的。在备选拖拽区域用两个方法来进行触发。

<template><div><div><div class="layoutJSON">Displayed as <code>[x, y, w, h]</code>:<div class="columns"><div class="layoutItem" v-for="item in layout"><b>{{ item.i }}</b>: [{{ item.x }}, {{ item.y }}, {{ item.w }}, {{ item.h }}]</div></div></div></div><br/><div @drag="drag" @dragend="dragend" class="droppable-element" draggable="true"unselectable="on">Droppable Element (Drag me!)</div><div id="content"><grid-layout ref="gridlayout" :layout.sync="layout":col-num="12":row-height="30":is-draggable="true":is-resizable="true":vertical-compact="true":use-css-transforms="true"><grid-item :key="item.i" v-for="item in layout":x="item.x":y="item.y":w="item.w":h="item.h":i="item.i"><span class="text">{{ item.i }}</span></grid-item></grid-layout></div></div>
</template>

 其他更多的官方说明,请参考

Installation | Vue Grid Layout - ️A grid layout system for Vue.js


<template><div><div><div class="layoutJSON">Displayed as <code>[x, y, w, h]</code>:<div class="columns"><div class="layoutItem" v-for="item in layout"><b>{{ item.i }}</b>: [{{ item.x }}, {{ item.y }}, {{ item.w }}, {{ item.h }}]</div></div></div></div><br/><div @drag="drag" @dragend="dragend" class="droppable-element" draggable="true"unselectable="on">Droppable Element (Drag me!)</div><div id="content"><grid-layout ref="gridlayout" :layout.sync="layout":col-num="12":row-height="30":is-draggable="true":is-resizable="true":vertical-compact="true":use-css-transforms="true"><grid-item :key="item.i" v-for="item in layout":x="item.x":y="item.y":w="item.w":h="item.h":i="item.i"><span class="text">{{ item.i }}</span></grid-item></grid-layout></div></div>
</template><script>
import {GridLayout, GridItem} from "vue-grid-layout"
let mouseXY = {"x": null, "y": null};
let DragPos = {"x": null, "y": null, "w": 1, "h": 1, "i": null};
export default {components: {GridLayout,GridItem},data() {return {layout: [{"x": 0, "y": 0, "w": 2, "h": 2, "i": "0"},{"x": 2, "y": 0, "w": 2, "h": 4, "i": "1"},{"x": 4, "y": 0, "w": 2, "h": 5, "i": "2"},{"x": 6, "y": 0, "w": 2, "h": 3, "i": "3"},{"x": 8, "y": 0, "w": 2, "h": 3, "i": "4"},{"x": 10, "y": 0, "w": 2, "h": 3, "i": "5"},{"x": 0, "y": 5, "w": 2, "h": 5, "i": "6"},{"x": 2, "y": 5, "w": 2, "h": 5, "i": "7"},{"x": 4, "y": 5, "w": 2, "h": 5, "i": "8"},{"x": 5, "y": 10, "w": 4, "h": 3, "i": "9"},],}},mounted() {document.addEventListener("dragover", function (e) {mouseXY.x = e.clientX;mouseXY.y = e.clientY;}, false);},beforeDestroy() {},methods: {drag: function (e) {let parentRect = document.getElementById('content').getBoundingClientRect();let mouseInGrid = false;if (((mouseXY.x > parentRect.left) && (mouseXY.x < parentRect.right)) && ((mouseXY.y > parentRect.top) && (mouseXY.y < parentRect.bottom))) {mouseInGrid = true;}if (mouseInGrid === true && (this.layout.findIndex(item => item.i === 'drop')) === -1) {this.layout.push({x: (this.layout.length * 2) % (this.colNum || 12),y: this.layout.length + (this.colNum || 12), // puts it at the bottomw: 1,h: 1,i: 'drop',});}let index = this.layout.findIndex(item => item.i === 'drop');if (index !== -1) {try {this.$refs.gridlayout.$children[this.layout.length].$refs.item.style.display = "none";} catch {}let el = this.$refs.gridlayout.$children[index];el.dragging = {"top": mouseXY.y - parentRect.top, "left": mouseXY.x - parentRect.left};let new_pos = el.calcXY(mouseXY.y - parentRect.top, mouseXY.x - parentRect.left);if (mouseInGrid === true) {this.$refs.gridlayout.dragEvent('dragstart', 'drop', new_pos.x, new_pos.y, 1, 1);DragPos.i = String(index);DragPos.x = this.layout[index].x;DragPos.y = this.layout[index].y;}if (mouseInGrid === false) {this.$refs.gridlayout.dragEvent('dragend', 'drop', new_pos.x, new_pos.y, 1, 1);this.layout = this.layout.filter(obj => obj.i !== 'drop');}}},dragend: function (e) {let parentRect = document.getElementById('content').getBoundingClientRect();let mouseInGrid = false;if (((mouseXY.x > parentRect.left) && (mouseXY.x < parentRect.right)) && ((mouseXY.y > parentRect.top) && (mouseXY.y < parentRect.bottom))) {mouseInGrid = true;}if (mouseInGrid === true) {alert(`Dropped element props:\n${JSON.stringify(DragPos, ['x', 'y', 'w', 'h'], 2)}`);this.$refs.gridlayout.dragEvent('dragend', 'drop', DragPos.x, DragPos.y, 1, 1);this.layout = this.layout.filter(obj => obj.i !== 'drop');// UNCOMMENT below if you want to add a grid-item/*this.layout.push({x: DragPos.x,y: DragPos.y,w: 1,h: 1,i: DragPos.i,});this.$refs.gridLayout.dragEvent('dragend', DragPos.i, DragPos.x,DragPos.y,1,1);try {this.$refs.gridLayout.$children[this.layout.length].$refs.item.style.display="block";} catch {}*/}},}
}
</script><style scoped>
.droppable-element {width: 150px;text-align: center;background: #fdd;border: 1px solid black;margin: 10px 0;padding: 10px;
}
.vue-grid-layout {background: #eee;
}
.vue-grid-item:not(.vue-grid-placeholder) {background: #ccc;border: 1px solid black;
}
.vue-grid-item .resizing {opacity: 0.9;
}
.vue-grid-item .static {background: #cce;
}
.vue-grid-item .text {font-size: 24px;text-align: center;position: absolute;top: 0;bottom: 0;left: 0;right: 0;margin: auto;height: 100%;width: 100%;
}
.vue-grid-item .no-drag {height: 100%;width: 100%;
}
.vue-grid-item .minMax {font-size: 12px;
}
.vue-grid-item .add {cursor: pointer;
}
.vue-draggable-handle {position: absolute;width: 20px;height: 20px;top: 0;left: 0;background: url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='10'><circle cx='5' cy='5' r='5' fill='#999999'/></svg>") no-repeat;background-position: bottom right;padding: 0 8px 8px 0;background-repeat: no-repeat;background-origin: content-box;box-sizing: border-box;cursor: pointer;
}
.layoutJSON {background: #ddd;border: 1px solid black;margin-top: 10px;padding: 10px;
}
.layoutJSON {background: #ddd;border: 1px solid black;margin-top: 10px;padding: 10px;
}
.columns {-moz-columns: 120px;-webkit-columns: 120px;columns: 120px;
}
</style>

【注意 : 其中两个方法应该是会有 bug 】


事件

每一个栅格元素grid-item上都可以添加监听器,用于监听移动和调整大小事件,这样父级Vue对象就可以收到通知。

示例

    <grid-layout:layout="layout":col-num="12":row-height="30":is-draggable="true":is-resizable="true":vertical-compact="true":margin="[10, 10]":use-css-transforms="true"@layout-created="layoutCreatedEvent"@layout-before-mount="layoutBeforeMountEvent"@layout-mounted="layoutMountedEvent"@layout-ready="layoutReadyEvent"@layout-updated="layoutUpdatedEvent"><grid-item v-for="item in layout":x="item.x":y="item.y":w="item.w":h="item.h":i="item.i":key="item.i"@resize="resizeEvent"@move="moveEvent"@resized="resizedEvent"@moved="movedEvent">{{item.i}}</grid-item></grid-layout>
  • layoutCreatedEvent

    对应Vue生命周期的created

    layoutCreatedEvent: function(newLayout){console.log("Created layout: ", newLayout)}
  • layoutBeforeMountEvent

    对应Vue生命周期的beforeMount

    layoutBeforeMountEvent: function(newLayout){console.log("beforeMount layout: ", newLayout)}
  • layoutMountedEvent

    对应Vue生命周期的mounted

    layoutMountedEvent: function(newLayout){console.log("Mounted layout: ", newLayout)}
  • layoutReadyEvent

    当完成mount中的所有操作时生成的事件

    layoutReadyEvent: function(newLayout){console.log("Ready layout: ", newLayout)}
  • layoutUpdatedEvent

    更新事件(布局更新或栅格元素的位置重新计算)

    layoutUpdatedEvent: function(newLayout){console.log("Updated layout: ", newLayout)}
  • moveEvent

    移动时的事件

    moveEvent: function(i, newX, newY){console.log("MOVE i=" + i + ", X=" + newX + ", Y=" + newY);},
  • resizeEvent

    调整大小时的事件

    resizeEvent: function(i, newH, newW, newHPx, newWPx){console.log("RESIZE i=" + i + ", H=" + newH + ", W=" + newW + ", H(px)=" + newHPx + ", W(px)=" + newWPx);},
  • movedEvent

    移动后的事件

    movedEvent: function(i, newX, newY){console.log("MOVED i=" + i + ", X=" + newX + ", Y=" + newY);},
  • resizedEvent

    调整大小后的事件

    /**** @param i the item id/index* @param newH new height in grid rows* @param newW new width in grid columns* @param newHPx new height in pixels* @param newWPx new width in pixels**/resizedEvent: function(i, newH, newW, newHPx, newWPx){console.log("RESIZED i=" + i + ", H=" + newH + ", W=" + newW + ", H(px)=" + newHPx + ", W(px)=" + newWPx);},

http://chatgpt.dhexx.cn/article/baSfktDU.shtml

相关文章

vue2 使用 Sortable 库进行拖拽操作

一、vue 项目使用 文档地址&#xff1a; https://www.itxst.com/sortablejs/neuinffi.html 1、安装依赖 npm i -S vuedraggable2、.vue 文件引入组件 import draggable from "vuedraggable"; components: { draggable },3、.使用 查看文档中的示例即可&#xff…

空指针、悬空指针、野指针

文章目录 前言一、指针&#xff1f;二、指针的应用场景三、 空指针四、 悬空指针五、 野指针正确用法 总结 前言 相信很多小伙伴对指针的使用都有一定的了解了。但更多的人可能对指针又爱又恨。这次我们谈点重要的&#xff0c;进一步加深对指针的理解 一、指针&#xff1f; 指…

【C语言】指针(野指针)

目录 1&#xff1a;什么是野指针&#xff1f; 2&#xff1a;如何规避野指针 1.1&#xff1a;指针变量的初始化 2.2&#xff1a;指针越界访问 3.3&#xff1a;指针指向的空间如果我们还回去的话&#xff0c;就把指针指针置为NULL 4.4&#xff1a;指针使用之前检查有效性…

C语言的野指针

1.野指针 指针变量中的值是非法的内存地址&#xff0c;进而形成野指针野指针不是NULL指针&#xff0c;是指向不可用内存地址的指针NULL指针并无危害&#xff0c;很好判断&#xff0c;也很好调试C语言中无法判断一个指针所保存的地址是否合法&#xff0c;合法的地址是通过变量或…

初识C语言---野指针

野指针概念&#xff1a; 野指针就是指针指向的位置是不可知的&#xff08;随机的、不正确的、没有明确限制的&#xff09;。 一、野指针成因 1、指针未初始化就使用 #include<stdio.h> int main() {int* p; *p 10; return 0; }此段代码中&#…

野指针(概念,产生原因,危害,避免方法)

思维导图: 1.野指针与垂悬指针的区别: 野指针:访问一个已销毁或者访问受限的内存区域的指针,野指针不能判断是否为NULL来避免 垂悬指针:指针正常初始化,曾指向一个对象,该对象被销毁了,但是指针未制空,那么就成了悬空指针。 2.概念 指针指向了一块随机的空间,不受…

野指针概念、定义、及如何规避野指针

野指针 野指针的概念&#xff1a; 野指针就是指针指向的位置不可知的。&#xff08;随机的、不正确的、没有明确限制的&#xff09; 野指针的三种情况 1、指针未定义 #include <stdio.h> int main() {int* p; //局部变量指针未初始化&#xff0c;默认就是随机值*p10;r…

使用 OKTA 作为 SAML IdP 为 FortiClient配置 SAML SSO 登录

描述 随着用于 FortiGate 和 FortiClient 6.4 的 FortiOS 6.4 的发布,现在可以创建SSL SSO 单点登录解决方案,该解决方案可以集成第三方 SAML SSO 身份提供商 (IdP) 并利用其 MFA 功能。 前置条件 FortiGate 运行 FortiOS 6.4.0 或更高版本FortiClient 6.4.0 或更高版本OK…

SAML 流程讲解

SAML&#xff08;Security Assert Mark Language&#xff09;常用来实现SSO。 本文主要梳理一下SAML的代码逻辑 术语讲解&#xff1a; IDP: Identity provider 在单点登陆中是指统一身份认证平台。 SP&#xff1a;Service Provider 在单点登陆中是指需要被认证的服务方。 A…

SAML单点登录-spring-security-saml 整合使用

本文链接&#xff1a;http://t.csdn.cn/BIGKc SAML单点登录-spring-security-saml客户端SP 使用spring-security-saml搭建SAML协议的客户端&#xff0c;该依赖是spring框架的官方库&#xff0c;配置方便、文档详细。提供了包括单点登录、单点登出、获取sq元数据文件等接口&…

盘点认证协议 : 普及篇之SAML

首先分享之前的所有文章 , 欢迎点赞收藏转发三连下次一定 >>>> &#x1f61c;&#x1f61c;&#x1f61c; 文章合集 : &#x1f381; https://juejin.cn/post/6941642435189538824 Github : &#x1f449; https://github.com/black-ant CASE 备份 : &#x1f449…

SAML2.0 笔记(二)

文章目录 零、示例代码参考一、前言二、共通内容1.1、引入依赖1.2、初始化SAML部分1.2.1、检查JCE环境1.2.2、初始化服务 1.3、拦截器部分1.3.1、构建AuthnRequest1.3.2、AuthRequest解析1.3.3、SP模式选择1.3.4、IDP模式选择 1.4、涉及的工具类1.4.1、OpenSAMLUtils工具类1.4.…

SAML单点登录-spring-security-saml客户端SP

SAML单点登录-spring-security-saml客户端SP 使用spring-security-saml搭建SAML协议的客户端&#xff0c;该依赖是spring框架的官方库&#xff0c;配置方便、文档详细。提供了包括单点登录、单点登出、获取sq元数据文件等接口&#xff0c;无需自己实现&#xff0c;参考&#x…

SAML入门

SAML (Security Assertion Markup Language)入门 提到SAML (Security Assertion Markup Language), 很多人都会联想到单点登录SSO。那么Saml到底是什么&#xff0c;它跟sso到底有什么联系&#xff1f;这里给大家分享一下我在读完了saml差不多全部规范之后的一些心得。希望给sa…

SAML

SAML SAML&#xff08;Security Assertion Markup Language&#xff09;是一个基于XML的开源标准数据格式&#xff0c;它在当事方之间交换身份验证和授权数据&#xff0c;尤其是在身份提供者和服务提供者之间交换。SAML2.0可以实现基于网络跨域的单点登录&#xff08;SSO&…

基于SAML的单点登录介绍

一、背景知识&#xff1a; SAML即安全断言标记语言&#xff0c;英文全称是Security Assertion Markup Language。它是一个基于XML的标准&#xff0c;用于在不同的安全域(security domain)之间交换认证和授权数据。在SAML标准定义了身份提供者(identity provider)和服务提供者(s…

走进SAML——基础篇

SAML的全称是Security Assertion Markup Language。提到SAML&#xff0c;我们主要想到的是其在各种单点登录场景中大行其道。单点登录我们通常叫做SSO&#xff0c;那么SAML到底是如何实现SSO的呢&#xff1f;在这个系列的文章中&#xff0c;我将为大家阐释清楚。不过&#xff0…

深入浅出SAML协议

SAML概述 SAML&#xff08;Security Assertion Markup Language 安全断言标记语言&#xff09;是一个基于XML的开源标准数据格式&#xff0c;为在安全域间交换身份认证和授权数据&#xff0c;尤其是在IDP&#xff08;Identity Provider身份提供方&#xff09;和SP&#xff08;…

SAML2.0 笔记(一)

文章目录 一、前言二、初识概念1、SP & IDP 的概念2、认识元数据2.1 IDP MetaData2.1.1 SingleLogoutService2.1.2 SingleSignOnService 2.2 SP MetaData2.2.1 SingleLogoutService2.2.2 AssertionConsumerService 2.3 通用节点2.3.1 EntityId2.3.2 KeyDescriptor2.3.3 Nam…

【学习笔记】白盒及黑盒测试方法简介

目录 测试用例什么是测试用例测试用例的要素 白盒测试白盒测试的基本介绍白盒测试用例设计方法一、 逻辑覆盖法1.语句覆盖2. 判定覆盖3.条件覆盖4.判定-条件覆盖5.条件组合覆盖6.路径覆盖 二、基本路径测试法总结 黑盒测试分类功能测试性能测试 测试设计方法1.等价类法2.边界值…