【脚本工具】SVG路径中的A指令转DXF的圆弧和椭圆弧 C++代码实现

news2025/1/19 7:57:16

文章目录

  • 一、SVG路径的A指令的语法说明
  • 二、DXF中的圆弧和椭圆弧对象
    • 2.1 圆弧对象
    • 2.2 椭圆弧对象
  • 三、转DXF圆弧
    • 3.1 数学公式
    • 3.2 代码实现
    • 3.3 转换效果展示
  • 四、转DXF椭圆弧
    • 4.1 数学公式
    • 4.2 代码实现
    • 4.3 转换效果展示


一、SVG路径的A指令的语法说明

目前Svg的Arc的参数字符串如下:其中,A (绝对) a (相对)

A  rx  ry  x-axis-rotation  large-arc-flag  sweep-flag  x  y 
a  rx  ry  x-axis-rotation  large-arc-flag  sweep-flag  x  y 

除了A(a)表示标识为圆弧之外,其余参数说明如下:

参数说明符号
rx椭圆半长轴 a a a
ry椭圆半短轴 b b b
x-axis-rotation椭圆相对于坐标系的旋转角度,角度数而非弧度数 α \alpha α
large-arc-flag是否优(大)弧:0否,1是 f l f_l fl
sweep-flag绘制方向:0逆时针,1顺时针 f s f_s fs
x圆弧终点的x坐标 x e x_{e} xe
y圆弧终点的y坐标 y e y_{e} ye

实际上,我们也可以得到圆弧起点的坐标(即上一段图像的终点):

说明符号
圆弧起点的x坐标 x s x_{s} xs
圆弧起点的y坐标 y s y_{s} ys

二、DXF中的圆弧和椭圆弧对象

2.1 圆弧对象

class DXFArc
{
public:
	double cx; // 圆心X坐标
	double cy; // 圆心Y坐标
	double radius; // 圆弧半径
	double bangle; // 起点角度
	double eangle; // 终点角度
};

2.2 椭圆弧对象

class DXFEllipse
{
public:
	double cx; // 椭圆心X坐标
	double cy; // 椭圆心Y坐标
	double mx; // 长轴端点相对于中点的X坐标
	double my; // 长轴端点相对于中点的Y坐标
	double ratio; // 短半轴长度➗长半轴长度
	double angle1; // 起始弧度
	double angle2; // 终止弧度
};

三、转DXF圆弧

3.1 数学公式

圆弧可以看作一个长半轴等于短半轴(即满足 a = b = r a=b=r a=b=r)的特殊椭圆弧,因此,下面统一用长半轴 a a a 代替半径 r r r

另外,圆弧的 α = 0 \alpha = 0 α=0

第一步:计算圆弧中心 ( c x , c y ) (c_x,c_y) (cx,cy)

x 1 ′ = ( x s − x e ) / 2 y 1 ′ = ( y s − y e ) / 2 m = ± ∣ a 4 − a 2 y 1 ′ 2 − a 2 x 1 ′ 2 ∣ / ( a 2 ( y 1 ′ 2 + x 1 ′ 2 ) ) ( 仅当 l f = l s 时取 − , 其余时候取 + ) ⇓ c x ′ = m y 1 ′ c y ′ = − m x 1 ′ ⇓ c x = c x ′ + ( x s + x e ) / 2 c y = c y ′ + ( y s + y e ) / 2 x_1'=(x_s-x_e)/2\\ y_1'= (y_s-y_e)/2\\ m=±\sqrt{|a^4-a^2y_1'^2-a^2x_1'^2|/(a^2(y_1'^2+x_1'^2))} \quad (仅当l_f=l_s时取-,其余时候取+)\\ \Downarrow\\ c_x'=m y_1'\\ c_y'=-mx_1'\\ \Downarrow\\ c_x=c_x'+(x_s+x_e)/2\\ c_y=c_y'+(y_s+y_e)/2\\ x1=(xsxe)/2y1=(ysye)/2m=±a4a2y1′2a2x1′2∣/(a2(y1′2+x1′2)) (仅当lf=ls时取,其余时候取+)cx=my1cy=mx1cx=cx+(xs+xe)/2cy=cy+(ys+ye)/2

第二步:计算起始和终止角度 ( b a n g l e , e a n g l e ) (bangle,eangle) (bangle,eangle)

根据圆的参数方程,可以通过代入点 ( x , y ) (x,y) (x,y),从而反推出该点的角度 t t t

{ x = a ⋅ c o s ( t ) + c x y = a ⋅ s i n ( t ) + c y ⇓ t = ± a r c c o s ( ( x − c x ) / a ) \begin{cases} x=a · cos(t)+c_x \\ y=a · sin(t) + c_y \end{cases}\\ \Downarrow\\ t=±arccos((x-c_x)/a) {x=acos(t)+cxy=asin(t)+cyt=±arccos((xcx)/a)

其中, t t t 的符号和 a r c s i n ( ( y − c y ) / a ) arcsin((y-c_y)/a) arcsin((ycy)/a) 的相同。

基于此,我们可以通过将圆弧的起点 ( x s , y s ) (x_s,y_s) (xs,ys) 和终点 ( x e , y e ) (x_e,y_e) (xe,ye) 分别代入圆的参数方程,反推出圆弧的起始和终止角度 ( b a n g l e , e a n g l e ) (bangle,eangle) (bangle,eangle)

3.2 代码实现

// 圆周率
#define PI acos(-1)
// 浮点型数据精度
#define ERROR 0.00000001

// 根据圆的参数方程和圆上一个点的坐标,计算该点的角度
// r:圆弧半径
// (cx,cy):圆弧的中心点
// (x,y):圆弧上某点的坐标
double calcArcPointAngle(double r, double cx, double cy, double x, double y){
	double res = acos((x - cx)/r);
	if (asin((y - cy)/r) < 0){
		res = -res;
	}
	return res / PI * 180;
}

// 传入SVG的A指令的相关参数,返回对应的DXF中的圆弧对象
// a:圆弧半径
// lf:是否优(大)弧:0否,1是
// sf:绘制方向:0逆时针,1顺时针
// (startX,startY):圆弧的起点
// (endX,endY):圆弧的终点
DXFArc getDXFArcBySvg(double a,int lf,int sf,double startX,double startY,double endX,double endY){
	DXFArc arc = DXFArc();
	// 圆弧半径
	arc.radius = a;
	// 计算中点(cx,cy)
	double x1Pie = 0.5 * (startX - endX);
	double y1Pie = 0.5 * (startY - endY);
	double m = sqrt(abs(a*a*a*a - a*a*y1Pie*y1Pie - b*b*x1Pie*x1Pie) / (a*a* (y1Pie*y1Pie+x1Pie*x1Pie)));
	if (lf == sf){
		m = -m;
	}
	double cxPie = m * y1Pie;
	double cyPie = m * -x1Pie;
	arc.cx = cxPie + 0.5 * (startX + endX);
	arc.cy = cyPie + 0.5 * (startY + endY);
	// 计算角度(bangle,eangle)
	arc.bangle = calcArcPointAngle(a, arc.cx, arc.cy,startX,startY);
	arc.eangle = calcArcPointAngle(a, arc.cx, arc.cy, endX, endY);
	// 修正角度
	while (arc.eangle < arc.bangle){
		arc.eangle += 360.0;
	}
	if ((lf == 1 && arc.eangle - arc.bangle < 180.0) || (lf == 0 && arc.eangle - arc.bangle > 180.0)){
		double temp = arc.bangle;
		arc.bangle = arc.eangle;
		arc.eangle = temp;
	}
	// 返回转化好的圆弧
	return arc;
}

3.3 转换效果展示

SVG显示效果如下

在这里插入图片描述

转化为DXF后的显示效果如下

在这里插入图片描述


四、转DXF椭圆弧

4.1 数学公式

第一步:计算椭圆弧中心 ( c x , c y ) (c_x,c_y) (cx,cy)

x 1 ′ = c o s ( α ) ⋅ ( x s − x e ) / 2 + s i n ( α ) ⋅ ( y s − y e ) / 2 y 1 ′ = − s i n ( α ) ⋅ ( x s − x e ) / 2 + c o s ( α ) ⋅ ( y s − y e ) / 2 m = ± ∣ a 2 b 2 − a 2 y 1 ′ 2 − b 2 x 1 ′ 2 ∣ / ( a 2 y 1 ′ 2 + b 2 x 1 ′ 2 ) ( 仅当 l f = l s 时取 − , 其余时候取 + ) ⇓ c x ′ = m ( a y 1 ′ ) / b c y ′ = − m ( b x 1 ′ ) / a ⇓ c x = c o s ( α ) ⋅ c x ′ − s i n ( α ) ⋅ c y ′ + ( x s + x e ) / 2 c y = s i n ( α ) ⋅ c x ′ + c o s ( α ) ⋅ c y ′ + ( y s + y e ) / 2 x_1'=cos(\alpha)·(x_s-x_e)/2+sin(\alpha)·(y_s-y_e)/2\\ y_1'= -sin(\alpha)·(x_s-x_e)/2+cos(\alpha)·(y_s-y_e)/2\\ m=±\sqrt{|a^2b^2-a^2y_1'^2-b^2x_1'^2|/(a^2y_1'^2+b^2x_1'^2)} \quad (仅当l_f=l_s时取-,其余时候取+)\\ \Downarrow\\ c_x'=m(ay_1')/b\\ c_y'=-m(bx_1')/a\\ \Downarrow\\ c_x=cos(\alpha)·c_x'-sin(\alpha)·c_y'+(x_s+x_e)/2\\ c_y=sin(\alpha)·c_x'+cos(\alpha)·c_y'+(y_s+y_e)/2\\ x1=cos(α)(xsxe)/2+sin(α)(ysye)/2y1=sin(α)(xsxe)/2+cos(α)(ysye)/2m=±a2b2a2y1′2b2x1′2∣/(a2y1′2+b2x1′2) (仅当lf=ls时取,其余时候取+)cx=m(ay1)/bcy=m(bx1)/acx=cos(α)cxsin(α)cy+(xs+xe)/2cy=sin(α)cx+cos(α)cy+(ys+ye)/2

第二步:计算长轴端点相对中点的坐标 ( m x , m y ) (m_x,m_y) (mx,my)

m x = a ⋅ c o s ( α ) m y = ± a 2 − m x 2 ( 仅当 α < 0 时取 − ,其余时候取 + ) m_x=a·cos(\alpha)\\ m_y=±\sqrt{a^2-m_x^2} \quad (仅当\alpha<0时取-,其余时候取+)\\ mx=acos(α)my=±a2mx2 (仅当α<0时取,其余时候取+)

第三步:计算椭圆弧的起始和终止角度 ( a n g l e 1 , a n g l e 2 ) (angle1,angle2) (angle1,angle2)

根据椭圆的参数方程,可以通过代入点 ( x , y ) (x,y) (x,y),从而反推出该点的角度 t t t

{ x = a ⋅ c o s ( t ) ⋅ c o s ( α ) − b ⋅ s i n ( t ) ⋅ s i n ( α ) + c x y = a ⋅ c o s ( t ) ⋅ s i n ( α ) + b ⋅ s i n ( t ) ⋅ c o s ( α ) + c y ⇓ { c o s ( t ) = ( ( x − c x ) ⋅ c o s ( α ) + ( y − c y ) ⋅ s i n ( α ) ) / a s i n ( t ) = ( − ( x − c x ) ⋅ s i n ( α ) + ( y − c y ) ⋅ c o s ( α ) ) / b ⇓ t = ± a r c c o s ( ( ( x − c x ) ⋅ c o s ( α ) + ( y − c y ) ⋅ s i n ( α ) ) / a ) \begin{cases} x = a·cos(t)·cos(\alpha)-b·sin(t)·sin(\alpha)+c_x\\ y = a·cos(t)·sin(\alpha)+b·sin(t)·cos(\alpha)+c_y \end{cases}\\ \Downarrow\\ \begin{cases} cos(t) = ((x-c_x)·cos(\alpha)+(y-c_y)·sin(\alpha))/a\\ sin(t) = (-(x-c_x)·sin(\alpha)+(y-c_y)·cos(\alpha))/b\\ \end{cases}\\ \Downarrow\\ t=±arccos(((x-c_x)·cos(\alpha)+(y-c_y)·sin(\alpha))/a) {x=acos(t)cos(α)bsin(t)sin(α)+cxy=acos(t)sin(α)+bsin(t)cos(α)+cy{cos(t)=((xcx)cos(α)+(ycy)sin(α))/asin(t)=((xcx)sin(α)+(ycy)cos(α))/bt=±arccos(((xcx)cos(α)+(ycy)sin(α))/a)

其中, t t t 的符号和 a r c s i n ( ( − ( x − c x ) ⋅ s i n ( α ) + ( y − c y ) ⋅ c o s ( α ) ) / b ) arcsin((-(x-c_x)·sin(\alpha)+(y-c_y)·cos(\alpha))/b) arcsin(((xcx)sin(α)+(ycy)cos(α))/b) 的相同。

基于此,我们可以通过将圆弧的起点 ( x s , y s ) (x_s,y_s) (xs,ys) 和终点 ( x e , y e ) (x_e,y_e) (xe,ye) 分别代入椭圆的参数方程,反推出椭圆弧的起始和终止角度 ( a n g l e 1 , a n g l e 2 ) (angle1,angle2) (angle1,angle2)

4.2 代码实现

// 圆周率
#define PI acos(-1)
// 浮点型数据精度
#define ERROR 0.00000001

// 根据椭圆的参数方程和椭圆上一个点的坐标,计算该点的角度
// a:长轴半径
// b:短轴半径
// alpha:椭圆弧长半轴与x正半轴的夹角(弧度)
// (cx,cy):椭圆弧的中心点
// (x,y):椭圆弧上某点的坐标
double calcEllipsePointAngle(double a,double b,double alpha,double cx,double cy,double x,double y){
	double c = ((x - cx)*cos(alpha) + (y - cy)*sin(alpha)) / a;
	// 防止出现 acos(1.00000001)=-1.#IND的情况
	if (abs(c - 1) <= ERROR){
		c = 1;
	}
	// 防止出现 acos(-1.00000001)=-1.#IND的情况
	if (abs(c + 1) <= ERROR){
		c = -1;
	}
	double res = acos(c);
	c = (-(x - cx)*sin(alpha) + (y - cy)*cos(alpha)) / b;
	// 防止出现 asin(1.00000001)=-1.#IND的情况
	if (abs(c - 1) <= ERROR){
		c = 1;
	}
	// 防止出现 asin(-1.00000001)=-1.#IND的情况
	if (abs(c + 1) <= ERROR){
		c = -1;
	}
	if (asin(c) < 0){
		res = -res;
	}
	return res / PI * 180;
}

// 传入SVG的A指令的相关参数,返回对应的DXF中的椭圆弧对象
// a:长轴半径
// b:短轴半径
// lf:是否优(大)弧:0否,1是
// sf:绘制方向:0逆时针,1顺时针
// alpha:椭圆弧长半轴与x正半轴的夹角(弧度)
// (startX,startY):椭圆弧的起点
// (endX,endY):椭圆弧的终点
DXFEllipse getDXFEllipseBySvg(double a,double b,int lf,int sf,double alpha,double startX,double startY,double endX,double endY){
	DXFEllipse ellipse = DXFEllipse();
	// 短半轴长度➗长半轴长度
	ellipse.ratio = b / a;
	// 计算中点(cx,cy)
	double x1Pie = cos(alpha) * 0.5 * (startX - endX) + sin(alpha) * 0.5 * (startY - endY);
	double y1Pie = -sin(alpha) * 0.5 * (startX - endX) + cos(alpha) * 0.5 * (startY - endY);
	double m = sqrt(abs(a*a*b*b - a*a*y1Pie*y1Pie - b*b*x1Pie*x1Pie) / (a*a*y1Pie*y1Pie + b*b*x1Pie*x1Pie));
	if (lf == sf){
		m = -m;
	}
	double cxPie = m * ((a * y1Pie) / b);
	double cyPie = -m * ((b * x1Pie) / a);
	ellipse.cx = cos(alpha) * cxPie - sin(alpha) * cyPie + 0.5 * (startX + endX);
	ellipse.cy = sin(alpha) * cxPie + cos(alpha) * cyPie + 0.5 * (startY + endY);
	// 计算长轴端点相对中点的坐标(mx,my)
	ellipse.mx = a * cos(alpha);
	ellipse.my = sqrt(a*a - ellipse.mx*ellipse.mx);
	if (alpha < 0){
		ellipse.my = -ellipse.my;
	}
	// 计算角度(angle1,angle2)
	ellipse.angle1 = calcEllipsePointAngle(a, b, alpha, ellipse.cx, ellipse.cy, startX, startY) / 180.0 * PI;
	ellipse.angle2 = calcEllipsePointAngle(a, b, alpha, ellipse.cx, ellipse.cy, endX, endY) / 180.0 * PI;
	// 修正角度
	while (ellipse.angle2 < ellipse.angle1){
		ellipse.angle2 += (2 * PI);
	}
	if ((lf == 1 && ellipse.angle2 - ellipse.angle1 < PI) || (lf == 0 && ellipse.angle2 - ellipse.angle1 > PI)){
		double temp = ellipse.angle1;
		ellipse.angle1 = ellipse.angle2;
		ellipse.angle2 = temp;
	}
	// 返回转化好的椭圆弧
	return ellipse;
}

4.3 转换效果展示

SVG显示效果如下

在这里插入图片描述

转化为DXF后的显示效果如下

在这里插入图片描述


本博客的参考链接如下,第一章内容两篇都有借鉴。计算圆弧和椭圆弧中点的公式借鉴了第2个参考博客,公式与他的有所不同,增加了一个绝对值:

  1. SVG路径(path)中的圆弧(A)指令的语法说明及计算逻辑
  2. 根据SVG Arc求出其开始角、摆动角和椭圆圆心

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/576046.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

leetcode--分隔链表(java)

分割链表 leetcode 86 分割链表 &#xff08;中等&#xff09;解题思路&#xff1a;链表专题 leetcode 86 分割链表 &#xff08;中等&#xff09; leetcode 86 分割链表 原题链接&#xff0c;可以直接测试 给你一个链表的头节点 head 和一个特定值 x &#xff0c;请你对链表进…

怎么给苹果手机设备画面投屏到电脑上面?

虽然使用苹果设备自带的AirPlay功能&#xff0c;搭配其推出的Apple TV设备&#xff0c;可实现苹果设备的投屏播放&#xff0c;但相信很多人都不会花大价钱去购入Apple TV&#xff0c;如果是土豪的话请随意。 那么&#xff0c;没有Apple TV&#xff0c;苹果设备就不能投屏了吗&…

sql注入学习-知识点大合集

目录 &#xff08;一&#xff09;sql注入了解&#xff1a; 1.1什么是sql注入 1.2 sql注入的分类 &#xff08;二&#xff09;sql注入详解&#xff1a; 2.1.MySQL注入 2.2.1在MySQL注入中&#xff0c;会用到的知识 2.2.2mysql常用语句与常见 2.2.3msyql注入内容详解 2.2…

首发出炉Yolov5/Yolov7涨点神器:华为诺亚2023极简的神经网络模型 VanillaNet---VanillaBlock助力检测,实现暴力涨点

在​crack缺陷检测项目map 0.954提升至 0.979,涨点明显,博主多个数据集亲测有效,实现暴力涨点; 1.VanillaNet 论文:https://arxiv.org/pdf/2305.12972.pdf 来自华为诺亚、悉尼大学的研究者们提出了一种极简的神经网络模型 VanillaNet,以极简主义的设计为理念,网络中仅仅…

connect reset/timeout/reject 排查

异常排查 问题描述问题处理初步分析http配置即服务整体情况整体排查服务重启gcCPUJVM 暂存疑问点总结启动参数要配全监控体系健全科学使用jar包降配参数是参数得动态变 问题描述 最初出现的时候&#xff0c;是在每天的早上8-10这个时间范围内&#xff0c;服务A上的有一个接口时…

第一行代码 第十二章 Material Design实战

第12章 Material Design实战 其实长久以来&#xff0c;大多数人都认为Android系统的UI并不算美观&#xff0c;至少没有iOS系统的美观。以至于很多IT公司在进行应用界面设计的时候&#xff0c;为了保证双平台的统一性&#xff0c;强制要求Android端的界面风格必须和iOS端一致。…

Java08——继承

1. 继承 父类&#xff1a; package com.zsq.extend.improve_; //是pupil和graduate的父类 public class Student {public String name;public int age;private double score;public void info(){System.out.println("姓名&#xff1a;" name " 年龄&#xff1…

六级备考21天|CET-6|写作技巧2|13:00~14:40

目录 【一】写作技巧1的作业 [1]Creativity [2]谚语&#xff1a;值得做的就值得做得好 [3]Star chasing 追星​ [4]team spirit&communication 团队精神和交流 [5]谚语&#xff1a;理解​ 【二】谚语重要性开头模版 [1]谚语&#xff1a;Understand 理解 【三】社会…

【历史上的今天】4 月 26 日:验证码的发明者诞生;切尔诺贝利病毒爆发;诺基亚收购 Withings

整理 | 王启隆 透过「历史上的今天」&#xff0c;从过去看未来&#xff0c;从现在亦可以改变未来。 今天是 2023 年 4 月 26 日&#xff0c;在 2017 年的今天&#xff0c;中国首艘国产 001A 型航空母舰在大连完成了下水&#xff0c;从开工到下水&#xff0c;历时 3 年多时间。…

5月跳槽进字节跳动测试岗了,面试真简单...

前言: 最近金三银四跳槽季&#xff0c;相信很多小伙伴都在面试找工作&#xff0c; 怎样才能拿到大厂的offer&#xff0c;没有掌握绝对的技术&#xff0c;那么就要不断的学习&#xff0c;没有绝对的天才&#xff0c;只有持续不断的付出。对于我们每一个平凡人来说&#xff0c;…

利用Servlet编写第一个“hello world“

利用Servlet编写第一个"hello world" &#x1f50e;创建 Maven 项目&#x1f50e;引入依赖&#x1f50e;创建目录&#x1f50e;编写代码&#x1f50e;打包代码&#x1f50e;部署&#x1f50e;程序验证&#x1f50e;结尾 &#x1f50e;创建 Maven 项目 Maven 是一个构…

基于yolov5的车辆行人道路检测

一、数据集介绍 本实验使用自动驾驶的公开数据集BDD100K。   数据格式&#xff1a;BDD100K 数据集包含10万段高清视频&#xff0c;每个视频约40秒\720p\30 fps&#xff0c;总时间超过1,100小时。视频序列还包括GPS位置、IMU数据和时间戳&#xff1b;视频带有由手机记录的GPS/…

【刷题之路】LeetCode 1700. 无法吃午餐的学生数量

【刷题之路】LeetCode 1700. 无法吃午餐的学生数量 一、题目描述二、解题1、思路分析2、代码实现2.1、先将队列实现一2.2、代码实现 一、题目描述 原题连接&#xff1a; 1700. 无法吃午餐的学生数量 题目描述&#xff1a; 学校的自助午餐提供圆形和方形的三明治&#xff0c;分…

进程信号之产生

目录 &#x1f3c6;一、认识信号 &#x1f3c6;二、信号的产生 ①通过终端按键产生信号 ②调用系统函数向进程发信号 ③由硬件异常产生信号 ④软件条件产生信号 &#x1f3c6;三、进程退出时的核心转储的问题 &#x1f3c6;一、认识信号 生活中&#xff0c;有很多信号…

Python 下载的 11 种姿势,一种比一种高级

今天我们一起学习如何使用不同的Python模块从web下载文件。此外&#xff0c;你将下载常规文件、web页面、Amazon S3和其他资源。 通过本文的学习&#xff0c;你将学到如何克服可能遇到的各种挑战&#xff0c;例如下载重定向的文件、下载大型文件、完成一个多线程下载以及其他策…

面试官:你会从哪些维度进行MySQL性能优化?

面试官如果问你&#xff1a;你会从哪些维度进行MySQL性能优化&#xff1f;你会怎么回答&#xff1f; 所谓的性能优化&#xff0c;一般针对的是MySQL查询的优化。既然是优化查询&#xff0c;我们自然要先知道查询操作要经过哪些环节&#xff0c;然后思考可以在哪些环节进行优化…

English Learning - L3 作业打卡 Lesson3 Day21 2023.5.25 周四

English Learning - L3 作业打卡 Lesson3 Day21 2023.5.25 周四 引言&#x1f349;句1: Here is another expression about meat one man’s meat is another man’s poison.成分划分连读爆破语调 &#x1f349;句2: In other words, one person might like something very muc…

postMessage引发XSS

这次的主题是postMessage未验证消息来源origin&#xff0c;导致恶意代码注入的dom-xss&#xff0c;由于很少人关注这类型的注入&#xff0c;因为挖掘难度中等&#xff0c;需要一定的javascript代码审计能力&#xff0c;且漏洞危害等级不高&#xff0c;导致国内许多SRC都存在跨域…

【计算机网络】 7、websocket 概念、sdk、实现

文章目录 一、背景二、简介三、client3.1 ws 构造函数3.2 ws.readyState3.3 ws.onopen3.4 ws.onclose3.5 ws.onmessage3.6 ws.send3.7 ws.bufferedAmount3.8 ws.onerror 四、server4.1 go4.1.1 apifox client4.1.2 js client 五、范式 一、背景 已经有了 http 协议&#xff0c…

懂点自动化基础就要25k? 测试总监:给你15K,爱来不来

公司前段缺人&#xff0c;也面了不少测试&#xff0c;结果竟然没有一个合适的。一开始瞄准的就是中级的水准&#xff0c;也没指望来大牛&#xff0c;提供的薪资在10-25k&#xff0c;面试的人很多&#xff0c;但平均水平很让人失望。看简历很多都是3年工作经验&#xff0c;但面试…