前端的几种网络请求方式
网络请求
node编写接口
这里用到的几个包的作用
- express:基于 Node.js 平台,快速、开放、极简的 Web 开发框架,官网:https://www.expressjs.com.cn/
- cors:用来解决跨域问题
- body-parser:可以通过 req.body 获取post请求传递过来的json数据
- multer:用于文件上传
const express = require('express');
const fs = require("fs");
const path = require("path")
const app = express()
const multer = require("multer");
const cors = require("cors")
const bodyParser = require("body-parser")
app.use(cors())
app.use(bodyParser.json())
// 设置上传目录和文件名
const storage = multer.diskStorage({destination: function (req, file, cb) {cb(null, 'uploads/')},filename: function (req, file, cb) {console.log(file)cb(null, Date.now() + path.extname(file.originalname))}
})const upload = multer({ storage: storage });app.get("/name",(req,res)=>{res.send({code:200,msg:"成功"})
})app.post("/add",(req,res)=>{console.log(req.body)// 使用req.body接收前端传递过来的post参数let data = req.bodyres.send({code:200,data:data})
})app.post("/upload", upload.single("file"), (req, res) => {if (!req.file) {return res.status(400).send('No file uploaded.');}// 输出文件信息console.log('Uploaded: ' + req.file.filename);res.send({code:200,data:'文件上传成功'})
});app.get("/sse", (req, res) => {// 声明链接方式是sseres.writeHead(200,{"Content-Type":"text/event-stream"})const text = fs.readFileSync("./read.txt","utf8")const arr = text.split("")let current = 0// 设置每隔20毫秒主动发送一次数据let timer = setInterval(()=>{if(current >= arr.length){clearInterval(timer)}else{// 发送消息必须是 data: 开头,\n\n 结尾。中间是发送的内容,内容必须是一个字符串res.write(`data:${arr[current]}\n\n`)current++}},20)
})app.listen(10086, () =>{console.log("启动成功: http://localhost:10086")
})
Ajax请求
发送GET请求
let xhr = new XMLHttpRequest()
function sendGet(){xhr.open("GET","http://127.0.0.1:10086/name")// 当接口相应数据后会触发onload回调xhr.onload = function (){if(xhr.status === 200){console.log(JSON.parse(xhr.responseText))}}xhr.send()
}
发送POST请求
let xhr = new XMLHttpRequest()
function sendPost(){xhr.open("POST","http://127.0.0.1:10086/add")xhr.setRequestHeader("Content-Type","application/json")xhr.onload = function (){if(xhr.status === 200){console.log(JSON.parse(xhr.responseText))}}// 定义发送给后端的数据let data = {name:"张三",age:18}// 把数据放在send中进行发送,需要使用JSON.stringify进行序列化xhr.send(JSON.stringify(data))
}
上传文件
var fileEl = document.getElementById("file");
fileEl.addEventListener("change",event=>{let file = event.target.files[0]xhr.open("POST","http://127.0.0.1:10086/upload")xhr.onload = function (){if(xhr.status === 200){console.log(JSON.parse(xhr.responseText))}}let data = new FormData()data.append("file",file)xhr.send(data)
})
设置超时时间
function sendGet() {xhr.open("GET", "http://127.0.0.1:10086/name")xhr.setRequestHeader("Content-Type", "application/json")// 设置超时时间1000毫秒xhr.timeout = 1000xhr.addEventListener("timeout", function () {console.log("请求超时")})xhr.onload = function () {if (xhr.status === 200) {console.log(JSON.parse(xhr.responseText))}}xhr.send()
}
请求中断
xhr.abort()
// 请求中断回调
xhr.addEventListener("abort",function (){console.log("请求中断")
})
监听上传进度
// 监听上传进度
xhr.addEventListener("progress",function (event){console.log(`${(event.loaded / event.total * 100).toFixed(2)}%`)
})
Axios使用
Axios 是对 Ajax 的封装,可以帮助我们更好的发送请求,官方文档:http://www.axios-js.com/zh-cn/docs/
下面是分别发送get和post的示例
<script src="https://unpkg.com/axios/dist/axios.min.js"></script>function axiosGet(){axios.get("http://127.0.0.1:10086/name").then(res=>{console.log(res.data)})
}function axiosPost(){axios.post("http://127.0.0.1:10086/add",{name:"张三"}).then(res=>{console.log(res.data)})
}
fetch请求
Fetch是一种网络通信协议,用于在客户端和服务器之间传输数据。该协议使用HTTP请求和响应进行通信,与传统的AJAX方式相比,Fetch更加简单易用,并提供了许多现代化的功能。
使用Fetch可以方便地向服务器发送请求,并将响应返回给客户端。你可以使用Fetch获取文本、JSON、图像和文件等数据,并进行各种处理。Fetch还支持流式传输和取消请求等高级功能,使得处理大型数据集和长时间运行的操作变得更加简单和可靠。
Fetch API也是Javascript中常用的API之一,它提供了一组方法和属性,可以在浏览器端与服务器进行通信。通过Fetch API,你可以轻松地使用Fetch协议进行数据传输,并对请求和响应进行操作和处理。
fetch 对比 xhr
fetch
和 XMLHttpRequest
(XHR)都是前端与服务器进行数据交互的常用方式,它们各有优缺点,下面是它们的比较:
- API 设计和使用方式
fetch
的 API 设计更加现代化、简洁和易于使用,使用起来更加直观和方便。相比之下,XHR 的 API 设计比较繁琐,需要进行多个参数的配置和回调函数的处理。
- 支持的请求方法
fetch
API 默认只支持 GET 和 POST 请求方法,而 XHR 则支持所有标准的 HTTP 请求方法。
- 请求头部
在 fetch
中设置请求头部的方式更加清晰和直接,可以通过 Headers
对象进行设置,而 XHR 的方式相对较为繁琐。
- 请求体
在发送 POST 请求时,fetch
API 要求将请求体数据作为参数传递给 fetch
方法中的 options
对象,而 XHR 可以直接在 send()
方法中设置请求体数据。
- 支持的数据类型
在解析响应数据时,fetch
API 提供了多种方法,包括 .json()
, .blob()
, .arrayBuffer()
等,而 XHR 只支持文本和二进制数据两种数据类型。
- 跨域请求
在进行跨域请求时,fetch
API 提供了一种简单而强大的解决方案——使用 CORS(跨域资源共享)头部实现跨域请求,而 XHR 则使用了一个叫做 XMLHttpRequest Level 2
的规范,在代码编写上相对较为繁琐。
总的来说,fetch
API 与 XHR 各有优缺点,具体选择哪种方式还需要根据具体情况进行考虑。平时开发中使用较多的是 fetch
,因为它使用方便、API 简洁、语法清晰,同时也支持了大多数常用的功能,可以有效地简化前端开发流程。
fetch 返回格式
- text(): 将响应体解析为纯文本字符串并返回。
- json(): 将响应体解析为JSON格式并返回一个JavaScript对象。
- blob(): 将响应体解析为二进制数据并返回一个Blob对象。
- arrayBuffer(): 将响应体解析为二进制数据并返回一个ArrayBuffer对象。
- formData(): 将响应体解析为FormData对象。
发送GET请求
function fetchGet() {fetch("http://localhost:10086/name").then(res => res.json()).then(res => {console.log(res)})
}
发送POST请求
function fetchPost() {fetch("http://localhost:10086/add", {method: "post",headers:{'Content-Type':'application/json'},body: JSON.stringify({name: "张三",age: 18})}).then(res => res.json()).then(res => {console.log(res)})
}
终止请求
需要使用 AbortController 构造器
<button onclick="fetchGet()">get请求</button>
<button onclick="stop()">终止请求</button>
发送请求
const abort = new AbortController()
function fetchGet() {fetch("http://localhost:10086/name",{signal:abort.signal}).then(res => res.json()).then(res => {console.log(res)})
}
调用终止方法
function stop(){abort.abort()
}
请求超时
fetch 本身没有超时定义,需要我们自己封装一个计时器,到时间后调用 abort.abort() 方法
const abort = new AbortController()
function fetchGet() {setTimeOutFn()fetch("http://localhost:10086/name",{signal:abort.signal}).then(res => res.json()).then(res => {console.log(res)})
}function setTimeOutFn(time = 2000){setTimeout(()=>{abort.abort()},time)
}
SSE
概述
SSE(Server-Sent Events)是一种用于实现服务器主动向客户端推送数据的技术,也被称为“事件流”(Event Stream)。它基于 HTTP 协议,利用了其长连接特性,在客户端与服务器之间建立一条持久化连接,并通过这条连接实现服务器向客户端的实时数据推送。
SSE 和 Socket 区别
SSE(Server-Sent Events)和 WebSocket 都是实现服务器向客户端实时推送数据的技术,但它们在某些方面还是有一定的区别。
- 技术实现
SSE 基于 HTTP 协议,利用了其长连接特性,通过浏览器向服务器发送一个 HTTP 请求,建立一条持久化的连接。而 WebSocket 则是通过特殊的升级协议(HTTP/1.1 Upgrade 或者 HTTP/2)建立新的 TCP 连接,与传统 HTTP 连接不同。
- 数据格式
SSE 可以传输文本和二进制格式的数据,但只支持单向数据流,即只能由服务器向客户端推送数据。WebSocket 支持双向数据流,客户端和服务器可以互相发送消息,并且没有消息大小限制。
- 连接状态
SSE 的连接状态仅有三种:已连接、连接中、已断开。连接状态是由浏览器自动维护的,客户端无法手动关闭或重新打开连接。而 WebSocket 连接的状态更灵活,可以手动打开、关闭、重连等。
- 兼容性
SSE 是标准的 Web API,可以在大部分现代浏览器和移动设备上使用。但如果需要兼容老版本的浏览器(如 IE6/7/8),则需要使用 polyfill 库进行兼容。而 WebSocket 在一些老版本 Android 手机上可能存在兼容性问题,需要使用一些特殊的 API 进行处理。
- 安全性
SSE 的实现比较简单,都是基于 HTTP 协议的,与普通的 Web 应用没有太大差异,因此风险相对较低。WebSocket 则需要通过额外的安全措施(如 SSL/TLS 加密)来确保数据传输的安全性,避免被窃听和篡改,否则可能会带来安全隐患。
总体来说,SSE 和 WebSocket 都有各自的优缺点,适用于不同的场景和需求。如果只需要服务器向客户端单向推送数据,并且应用在前端的浏览器环境中,则 SSE 是一个更加轻量级、易于实现和维护的选择。而如果需要双向传输数据、支持自定义协议、或者在更加复杂的网络环境中应用,则 WebSocket 可能更加适合。
适用于场景
chatGPT 返回的数据 就是使用的SSE 技术
实时数据大屏 如果只是需要展示 实时的数据可以使用SSE技术 而不是非要使用webSocket
使用
调用node端写好的 sse 接口,这个接口会每隔20毫秒主动向前端发送一次数据
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<style>.content{width: 400px;height: 400px;border: 1px solid #ddd;}
</style>
<body><div class="content" id="message"></div><button onclick="start()">开始</button><button onclick="close()">关闭</button>
</body>
<script>let sse = nullfunction start(){sse = new EventSource("http://localhost:10086/ssh")// 链接成功回调sse.onopen = ()=>{console.log("open")}// 监听消息sse.onmessage = (event)=>{console.log(event)// 默认监听message,这个可以定义// 默认数据也是在event的data属性中返回document.getElementById("message").innerHTML += event.data}// 链接失败回调sse.onerror = ()=>{console.log("onerror")}}function close(){console.log("关闭")sse.close()}
</script>
</html>
WebSocket
WebSocket是双向通信,客户端可以随时向服务端发送消息,反过来服务端也可以随时向客户端发送消息
双向通信
使用node定义接口
安装
npm install ws
编写接口
const ws = require("ws")// 创建服务
const wss = new ws.Server({port:8888},()=>{console.log("socket服务启动成功")
})// 监听链接成功提示
wss.on("connection",(socket)=>{console.log("客户端链接成功")socket.on("message",e=>{// 通过e.toString()获取前端传递过来的东西socket.send("我是服务器,我收到你的消息了,内容是:"+ e.toString())})
})
调用
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<input type="text" id="msg"/>
<button onclick="send()">发送</button>
<ul id="ul"></ul>
</body>
<script>let msg = document.querySelector("#msg")let ul = document.querySelector("#ul")// 链接let wss = new WebSocket("ws://localhost:8888")// 监听消息wss.addEventListener("message", e => {console.log(e.data)let li = document.createElement("li")li.innerText = e.dataul.appendChild(li)})function send() {// 发送消息wss.send(msg.value)msg.value = ""}
</script>
</html>
消息广播
默认一个链接只会收到自己与服务器之间的消息,不能收到其他链接接收的消息,我们通过如下方式来实现
// 监听链接成功提示
wss.on("connection",(socket)=>{console.log("客户端链接成功")socket.on("message",e=>{// 广播消息 wss.clients 存放了所有链接信息,遍历这个链接信息,给所有链接者发送消息wss.clients.forEach(client=>{// 通过e.toString()获取前端传递过来的东西client.send("我是服务器,我收到你的消息了,内容是:"+ e.toString())})})
})
心跳检测
在长时间没有发送消息交互,或者网络不好的情况下,websocket 会出现断掉的情况,我们可以通过心跳检测的机制,定时发送一次消息,实现链接保活
const ws = require("ws")// 创建服务
const wss = new ws.Server({port: 8888}, () => {console.log("socket服务启动成功")
})// 消息类型
const STATE = {HEART:1,MESSAGE:2
}// 监听链接成功提示
wss.on("connection", (socket) => {console.log("客户端链接成功")socket.on("message", e => {// 广播消息wss.clients.forEach(client => {// 通过e.toString()获取前端传递过来的东西client.send(JSON.stringify({type:STATE.MESSAGE,data:"我是服务器,我收到你的消息了,内容是:" + e.toString()}))})})// 添加心跳检测let headInterval = nulllet headCheck = () => {if(socket.readyState === ws.OPEN){socket.send(JSON.stringify({type:STATE.HEART,data:"我是心跳包"}))}else{clearInterval(headInterval)}}// 每隔500毫秒检测一次setInterval(headCheck,500)
})
同时前端需要区分不同的消息类型
// 监听消息
wss.addEventListener("message", e => {let li = document.createElement("li")let data = JSON.parse(e.data)if(data.type === 2){li.innerText = data.dataul.appendChild(li)}
})
navigator.sendBeacon
使用 navigator.sendBeacon
实现高效的数据上报
在 web 开发中,我们经常需要将用户行为或性能数据上报到服务器。为了不影响用户体验,开发者通常会在页面卸载时进行数据上报。然而,传统的数据上报方式,如 XMLHttpRequest
或 Fetch API
,容易受到页面卸载过程中的阻塞,导致数据丢失。为了解决这个问题,navigator.sendBeacon
API 被引入,它可以在页面卸载时安全、可靠地发送数据。
navigator.sendBeacon
对比 Ajax fetch
优点
- 不受页面卸载过程的影响,确保数据可靠发送。
- 异步执行,不阻塞页面关闭或跳转。
- 能够发送跨域请求。
缺点
- fetch 和 ajax 都可以发送任意请求 而 sendBeacon 只能发送POST
- fetch 和 ajax 可以传输任意字节数据 而 sendBeacon 只能传送少量数据(64KB 以内)
- fetch 和 ajax 可以定义任意请求头 而 sendBeacon 无法自定义请求头
- sendBeacon 只能传输
ArrayBuffer
、ArrayBufferView
、Blob
、DOMString
、FormData
或URLSearchParams
类型的数据 - 如果处于危险的网络环境,或者开启了广告屏蔽插件 此请求将无效
navigator.sendBeacon
应用场景
- 发送心跳包:可以使用
navigator.sendBeacon
发送心跳包,以保持与服务器的长连接,避免因为长时间没有网络请求而导致连接被关闭。 - 埋点:可以使用
navigator.sendBeacon
在页面关闭或卸载时记录用户在线时间,pv uv,以及错误日志上报 按钮点击次数。 - 发送用户反馈:可以使用
navigator.sendBeacon
发送用户反馈信息,如用户意见、bug 报告等,以便进行产品优化和改进
其他注意事项 type
ping请求 是html5 新增的 并且是sendBeacon 特有的 ping 请求 只能携带少量数据,并且不需要等待服务端响应,因此非常适合做埋点统计,以及日志统计相关功能。
使用方法
编写一个接口
const multer = require("multer");app.post("/ping",multer().none(),(req,res)=>{console.log(req.body.data)res.send("ok")
})
前端发送 navigation.sendBeacon 请求
function send() {let data = new FormData()data.append("data", JSON.stringify({name: "张三",age: 1}))navigator.sendBeacon("http://localhost:10086/ping", data)
}
后端接收到文件
浏览器相应数据
JWT鉴权
首先安装相关依赖
npm install jsonwebtoken express cors
- jsonwebtoken:用于生成token和验证token
- cors:处理跨域问题
接口编写
const express = require("express")
const cors = require("cors")
const jwt = require("jsonwebtoken")
const app = express()// 处理跨域问题
app.use(cors())
// 可以使用 req.body 获取post请求传递的json数据
app.use(express.json())
// token加盐
const KEY = "123456"// 白名单,包含不需要验证token的路径
const whitelist = ['/login'];
// 验证token的中间件
app.use((req, res, next) => {// 检查路径是否在白名单中if (whitelist.includes(req.path)) {console.log("3333")// 在白名单中,直接进入下一个中间件或请求处理函数next();} else {// 不在白名单中,需要验证tokenconst token = req.headers['authorization'];jwt.verify(token, KEY, (err, decode) =>{if(err){res.status(401).send('无效的token')}else{next()}})}
});// 登录接口
app.post("/login", (req, res) => {let data = req.bodyconsole.log(data)if(data.name === "admin" && data.pwd === "123456"){res.send({id:1,// 生成token,第一个参数是token携带的内容,第二是KEY,第三个是过期时间token:jwt.sign({id:1,name:data.name}, KEY, {expiresIn: "1h"})})}else{res.send({code:500,msg:"用户名或密码错误"})}
})// 获取集合信息
app.get("/list",(req,res)=>{res.send([{name:"lisi",age:1},{name:"wangwu",age:2},])
})app.listen(3000, () => {console.log("服务启动成功:http://localhost:3000")
})
前端调用
前端在发送请求时需要在请求头中携带token
login.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
<div>用户名: <input placeholder="用户名" id="name"/>密码: <input placeholder="密码" id="pwd"/><button onclick="login()">登录</button>
</div>
<script>function login() {let name = document.getElementById("name").value;let pwd = document.getElementById("pwd").value;axios.post("http://localhost:3000/login",{name,pwd}).then(res=>{if(res.data.token){alert("登录成功")localStorage.setItem("token",res.data.token)location.href = "./list.html"}else{alert("登录失败")localStorage.removeItem("token")}})}
</script>
</body>
</html>
list.html
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title><script src="https://unpkg.com/axios/dist/axios.min.js"></script>
</head>
<body>
<button onclick="list()">获取list</button>
</body>
<script>function list(){axios.get("http://localhost:3000/list",{headers: {'authorization': localStorage.getItem("token"),}}).then(res=>{console.log(res.data)})}
</script>
</html>
判断网络状态
获取是否联网
// 是否联网,返回true或者false,true表示已经联网,false表示没有联网
console.log(navigator.onLine)
获取网络环境
前端还可以判断用户当前所在网络的好坏
// 获取网络环境
console.log(navigator.connection)
返回的是一个 NetworkInformation 对象
XSS跨站脚本攻击
随着互联网的快速普及,越来越多的敏感信息被存储在网络上,例如个人身份信息、财务信息等。在当前数字化时代,这些安全问题变得更加突出。作为开发者,我们必须采取适当的防范措施,以确保用户数据的安全性。本文将着重探讨跨站脚本攻击(Cross-site scripting,XSS)这一常见的网络攻击方式,包括其定义、原理、危害、分类和防范措施,以帮助大家更好地预防此类安全风险。
概述
**定义:**跨站点脚本攻击,简称XSS,是指攻击者利用网站存在的漏洞,通过在网站中注入恶意脚本代码,从而使得用户在访问该网站时受到攻击。这些恶意脚本代码通常是JavaScript 代码,它们可以窃取用户的敏感信息,如用户名、密码等,并将这些信息发送到攻击者的服务器。
原理
XSS攻击的本质是利用Web应用程序中的漏洞,向网页注入恶意脚本代码,然后将这些代码嵌入到网页中,当其他用户访问这个网页时,恶意脚本将会被执行。
攻击者通常会在Web应用程序的输入框、评论框、搜索框等可输入内容的地方输入特定的脚本代码,这些代码可以被Web应用程序直接插入到网页中,导致网页上的所有用户都会受到攻击。
XSS攻击的原理包括以下几个步骤:
1、攻击者在Web应用程序的输入框、评论框等可输入内容的地方输入包含script标签的恶意脚本代码,例如:
<script>
// 在这里插入恶意脚本代码
</script>
2、Web应用程序将恶意脚本代码保存到数据库中或直接将其插入到网页的HTML代码中。
3、当其他用户访问这个网页时,浏览器会执行其中的恶意脚本代码。恶意脚本可以窃取用户的敏感信息,如登录凭证、浏览器历史记录、Cookie等,或者通过控制用户的浏览器来进行更多的攻击。
例如,以下是一段可以窃取用户Cookie的恶意脚本代码:
<script>
let cookieValue = document.cookie;
// 将cookieValue发送到攻击者的服务器
</script>
4、攻击者获取到用户的敏感信息后,可以进行更进一步的攻击,例如重定向到恶意网站、发起钓鱼攻击等。
预防工具
使用第三方库来预防,这里使用 xss,官网文档:https://www.npmjs.com/package/xss
<script src="https://rawgit.com/leizongmin/js-xss/master/dist/xss.js"></script>
<script>// apply function filterXSS in the same wayvar html = filterXSS('<script>alert("xss");</scr' + "ipt>");alert(html);
</script>
相关文章:

前端的几种网络请求方式
网络请求 node编写接口 这里用到的几个包的作用 express:基于 Node.js 平台,快速、开放、极简的 Web 开发框架,官网:https://www.expressjs.com.cn/cors:用来解决跨域问题body-parser:可以通过 req.body…...

Kubernetes技术与架构-存储 4
如上所示,Kubernetes集群支持动态申请存储资源,即集群管理员可以按照实际的需求动态地申请存储资源,集群管理员需要事先定义一个或者多个StorageClass存储类型的资源,Pod中的容器实例直接引用事先定义的StorageClass存储类型的资源…...

jbase编译与部署的优化
上一篇的演示只是涉及自动编译业务脚本。演示时候工程编译是超级慢的。因为把静态资源放在了Web工程下,每次编译都要拷贝,运行起码是1分钟,不能忍受,为此思考工程结构改解决这个问题,顺带方便开发的发布。运行WebLoade…...

Filter 和 Listener
Filter 表示过滤器。是JavaWeb三大组件(Servlet、Filter、Listener)之一。 过滤器可以把对资源的请求 拦截 下来。浏览器可以访问服务器上所有的资源,而在访问到这些资源之前可以使用过滤器拦截下来,也就是说在访问资源之前会先经…...
【正则表达式】中的“\b“
正则表达式是一种用于匹配字符串的强大工具,它可以用于各种编程语言中,可以用来在文本中查找、替换或验证符合某种规则的内容。 正则表达式中有很多特殊的符号,称为元字符,它们有着特殊的含义和作用。其中,“\b” 是其…...

FPGA高端项目:图像采集+GTP+UDP架构,高速接口以太网视频传输,提供2套工程源码加QT上位机源码和技术支持
目录 1、前言免责声明本项目特点 2、相关方案推荐我这里已有的 GT 高速接口解决方案我这里已有的以太网方案 3、设计思路框架设计框图视频源选择OV5640摄像头配置及采集动态彩条视频数据组包GTP 全网最细解读GTP 基本结构GTP 发送和接收处理流程GTP 的参考时钟GTP 发送接口GTP …...

数据库系统原理与实践 笔记 #7
文章目录 数据库系统原理与实践 笔记 #7数据库设计和E-R模型(续)转换为关系模式具有简单属性的实体集的表示复合属性多值属性联系集的表示模式的冗余—合并 实体-联系设计问题设计问题联系属性的布局 扩展的E-R特性特化概化属性继承特化/概化的设计约束聚集E-R图表示方法总结E-…...

【CesiumJS】(1)Hello world
介绍 Cesium 起源于2011年,初衷是航空软件公司(Analytical Graphics, Inc.)的一个团队要制作世界上最准确、性能最高且具有时间动态性的虚拟地球。取名"Cesium"是因为元素铯Cesium让原子钟非常准确(1967年,人们依据铯原子的振动而对…...

Docker 学习路线 5:在 Docker 中实现数据持久化
Docker 可以运行隔离的容器,包括应用程序和其依赖项,与主机操作系统分离。默认情况下,容器是临时的,这意味着容器中存储的任何数据在终止后都将丢失。为了解决这个问题并在容器生命周期内保留数据,Docker 提供了各种数…...

linux下使用vscode对C++项目进行编译
项目的目录结构 头文件swap.h 在自定义的头文件中写函数的声明。 // 函数的声明 void swap(int a,int b);swap.cpp 导入函数的声明,写函数的定义 #include "swap.h" // 双引号表示自定义的头文件 #include <iostream> using namespace std;// 函…...

LangChain+LLM实战---ChatGPT的即时插件套件制作
英文原文:Instant Plugins for ChatGPT: Introducing the Wolfram ChatGPT Plugin Kit 在一分钟内构建一个新插件 几周前,我们与OpenAI合作发布了Wolfram插件,使ChatGPT可以使用Wolfram语言和Wolfram|Alpha作为工具,在ChatGPT内部…...

包装印刷行业万界星空科技云MES解决方案
印刷业的机械化程度在国内制造行业内算是比较高的,不算是劳动密集型企业。如书本的装订、包装的模切、烫金、糊盒等都已经有了全自动设备。印刷厂除了部分手工必须采用人工外,大部分都可以采用机器,也就意味着可以由少量工人生产出大量产品。…...
Python教程---计算机语言简介
1.计算机编程语言的发展历程 计算机语言发展经历了三个阶段: 机器语言 - 机器语言通过二进制编码来编写程序,打孔织带机。 - 执行效率好,编写起来太麻烦 符号语言(汇编) - 使用符号来代替机器码 - 编写程序时…...

rhcsa-文件内容显示
浏览普通文件内容 浏览文件的命令 命令常用选项说明cat -n 对输出内容中的所有行标注行号 -b 对输出内容中的非空行标注行号 查看文件的内容head-num 指定需要显示文件num行的内容默认查看文前十行的内容tail -num 指定需要显示文件num行的内容 -f 使tail不停的去读取显示文…...

宠物养成猫狗商城门店问诊档案流量主小程序开发
宠物养成猫狗商城门店问诊档案流量主小程序开发 猫狗宠物养成商城门店问诊档案流量主小程序开发,这是一个充满趣味性和创新性的项目。通过将宠物养成游戏与商城、问诊服务、社交功能等相结合,为用户提供一站式的宠物养育体验。 在宠物养成方面&#x…...

应用安全四十二:SSO安全
一、什么是SSO SSO是单点登录(Single Sign On)的缩写,是指在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。这种方式减少了由登录产生的时间消耗,辅助了用户管理,是比较流行的企业业务整合的解决方案之一。 身份验证过程依赖于双方之间的信任关…...

【行云流水线实践】基于“OneBuild”方法对镜像进行快速装箱 | 京东云技术团队
在云原生领域,无论使用哪种编排调度平台,Kubernetes,DockerSwarm,OpenShift等,业务都需要基于镜像进行交付,我们在内部实践“Source-to-image”和链式构建,总而总结出“OneBuild”模式。 其核心…...

软件开发必备神器!一文读懂10款热门看板工具推荐!
看板(Kanban)是一种流行的框架,用于实施敏捷和DevOps软件开发。它要求实时沟通每个人的能力,并全面透明地展示正在进行的工作。工作项目在看板上以可视化方式表示,使项目经理和所有团队成员可以随时查看每个工作的状态…...

怎样提取视频提取的人声或伴奏?
有些小伙伴们进行音视频创作时,可能会需要提取音频的人声或者是伴奏。这里给大家推荐一个音分轨人声分离软件,支持一键提取音频人声和一键提取伴奏功能,可批量导入文件同步提取,简单高效,是音视频创作者的不二选择&…...

SpringBoot概述
SpringBoot是Spring提供的一个子项目,用于快速构建Spring应用程序。 SpringFramework:核心功能SpringData:数据获取SpringSecurity:认证授权SpringAMQP:消息传递SpringCloud:服务治理 SpringBoot新特性&…...

云启出海,智联未来|阿里云网络「企业出海」系列客户沙龙上海站圆满落地
借阿里云中企出海大会的东风,以**「云启出海,智联未来|打造安全可靠的出海云网络引擎」为主题的阿里云企业出海客户沙龙云网络&安全专场于5.28日下午在上海顺利举办,现场吸引了来自携程、小红书、米哈游、哔哩哔哩、波克城市、…...

vscode(仍待补充)
写于2025 6.9 主包将加入vscode这个更权威的圈子 vscode的基本使用 侧边栏 vscode还能连接ssh? debug时使用的launch文件 1.task.json {"tasks": [{"type": "cppbuild","label": "C/C: gcc.exe 生成活动文件"…...
C# SqlSugar:依赖注入与仓储模式实践
C# SqlSugar:依赖注入与仓储模式实践 在 C# 的应用开发中,数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护,许多开发者会选择成熟的 ORM(对象关系映射)框架,SqlSugar 就是其中备受…...

Android15默认授权浮窗权限
我们经常有那种需求,客户需要定制的apk集成在ROM中,并且默认授予其【显示在其他应用的上层】权限,也就是我们常说的浮窗权限,那么我们就可以通过以下方法在wms、ams等系统服务的systemReady()方法中调用即可实现预置应用默认授权浮…...
3403. 从盒子中找出字典序最大的字符串 I
3403. 从盒子中找出字典序最大的字符串 I 题目链接:3403. 从盒子中找出字典序最大的字符串 I 代码如下: class Solution { public:string answerString(string word, int numFriends) {if (numFriends 1) {return word;}string res;for (int i 0;i &…...
爬虫基础学习day2
# 爬虫设计领域 工商:企查查、天眼查短视频:抖音、快手、西瓜 ---> 飞瓜电商:京东、淘宝、聚美优品、亚马逊 ---> 分析店铺经营决策标题、排名航空:抓取所有航空公司价格 ---> 去哪儿自媒体:采集自媒体数据进…...
CMake控制VS2022项目文件分组
我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...
大语言模型(LLM)中的KV缓存压缩与动态稀疏注意力机制设计
随着大语言模型(LLM)参数规模的增长,推理阶段的内存占用和计算复杂度成为核心挑战。传统注意力机制的计算复杂度随序列长度呈二次方增长,而KV缓存的内存消耗可能高达数十GB(例如Llama2-7B处理100K token时需50GB内存&a…...
【无标题】路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论
路径问题的革命性重构:基于二维拓扑收缩色动力学模型的零点隧穿理论 一、传统路径模型的根本缺陷 在经典正方形路径问题中(图1): mermaid graph LR A((A)) --- B((B)) B --- C((C)) C --- D((D)) D --- A A -.- C[无直接路径] B -…...

数学建模-滑翔伞伞翼面积的设计,运动状态计算和优化 !
我们考虑滑翔伞的伞翼面积设计问题以及运动状态描述。滑翔伞的性能主要取决于伞翼面积、气动特性以及飞行员的重量。我们的目标是建立数学模型来描述滑翔伞的运动状态,并优化伞翼面积的设计。 一、问题分析 滑翔伞在飞行过程中受到重力、升力和阻力的作用。升力和阻力与伞翼面…...