前端的几种网络请求方式

news2024/11/28 13:38:59

网络请求

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.body
    res.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) => {
    // 声明链接方式是sse
    res.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))
}

image-20231104170332434

上传文件

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)
})

image-20231104172140646

image-20231104172206960

设置超时时间

function sendGet() {
    xhr.open("GET", "http://127.0.0.1:10086/name")
    xhr.setRequestHeader("Content-Type", "application/json")
    // 设置超时时间1000毫秒
    xhr.timeout = 1000
    xhr.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

fetchXMLHttpRequest(XHR)都是前端与服务器进行数据交互的常用方式,它们各有优缺点,下面是它们的比较:

  1. API 设计和使用方式

fetch 的 API 设计更加现代化、简洁和易于使用,使用起来更加直观和方便。相比之下,XHR 的 API 设计比较繁琐,需要进行多个参数的配置和回调函数的处理。

  1. 支持的请求方法

fetch API 默认只支持 GET 和 POST 请求方法,而 XHR 则支持所有标准的 HTTP 请求方法。

  1. 请求头部

fetch 中设置请求头部的方式更加清晰和直接,可以通过 Headers 对象进行设置,而 XHR 的方式相对较为繁琐。

  1. 请求体

在发送 POST 请求时,fetch API 要求将请求体数据作为参数传递给 fetch 方法中的 options 对象,而 XHR 可以直接在 send() 方法中设置请求体数据。

  1. 支持的数据类型

在解析响应数据时,fetch API 提供了多种方法,包括 .json(), .blob(), .arrayBuffer() 等,而 XHR 只支持文本和二进制数据两种数据类型。

  1. 跨域请求

在进行跨域请求时,fetch API 提供了一种简单而强大的解决方案——使用 CORS(跨域资源共享)头部实现跨域请求,而 XHR 则使用了一个叫做 XMLHttpRequest Level 2 的规范,在代码编写上相对较为繁琐。

总的来说,fetch API 与 XHR 各有优缺点,具体选择哪种方式还需要根据具体情况进行考虑。平时开发中使用较多的是 fetch ,因为它使用方便、API 简洁、语法清晰,同时也支持了大多数常用的功能,可以有效地简化前端开发流程。

fetch 返回格式

  1. text(): 将响应体解析为纯文本字符串并返回。
  2. json(): 将响应体解析为JSON格式并返回一个JavaScript对象。
  3. blob(): 将响应体解析为二进制数据并返回一个Blob对象。
  4. arrayBuffer(): 将响应体解析为二进制数据并返回一个ArrayBuffer对象。
  5. 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 都是实现服务器向客户端实时推送数据的技术,但它们在某些方面还是有一定的区别。

  1. 技术实现

SSE 基于 HTTP 协议,利用了其长连接特性,通过浏览器向服务器发送一个 HTTP 请求,建立一条持久化的连接。而 WebSocket 则是通过特殊的升级协议(HTTP/1.1 Upgrade 或者 HTTP/2)建立新的 TCP 连接,与传统 HTTP 连接不同。

  1. 数据格式

SSE 可以传输文本和二进制格式的数据,但只支持单向数据流,即只能由服务器向客户端推送数据。WebSocket 支持双向数据流,客户端和服务器可以互相发送消息,并且没有消息大小限制。

  1. 连接状态

SSE 的连接状态仅有三种:已连接、连接中、已断开。连接状态是由浏览器自动维护的,客户端无法手动关闭或重新打开连接。而 WebSocket 连接的状态更灵活,可以手动打开、关闭、重连等。

  1. 兼容性

SSE 是标准的 Web API,可以在大部分现代浏览器和移动设备上使用。但如果需要兼容老版本的浏览器(如 IE6/7/8),则需要使用 polyfill 库进行兼容。而 WebSocket 在一些老版本 Android 手机上可能存在兼容性问题,需要使用一些特殊的 API 进行处理。

  1. 安全性

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 = null
    function 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.data
        ul.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 = null
    let 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.data
        ul.appendChild(li)
    }
})

navigator.sendBeacon

使用 navigator.sendBeacon 实现高效的数据上报

在 web 开发中,我们经常需要将用户行为或性能数据上报到服务器。为了不影响用户体验,开发者通常会在页面卸载时进行数据上报。然而,传统的数据上报方式,如 XMLHttpRequestFetch API,容易受到页面卸载过程中的阻塞,导致数据丢失。为了解决这个问题,navigator.sendBeacon API 被引入,它可以在页面卸载时安全、可靠地发送数据。

navigator.sendBeacon 对比 Ajax fetch

优点

  1. 不受页面卸载过程的影响,确保数据可靠发送。
  2. 异步执行,不阻塞页面关闭或跳转。
  3. 能够发送跨域请求。

缺点

  1. fetch 和 ajax 都可以发送任意请求 而 sendBeacon 只能发送POST
  2. fetch 和 ajax 可以传输任意字节数据 而 sendBeacon 只能传送少量数据(64KB 以内)
  3. fetch 和 ajax 可以定义任意请求头 而 sendBeacon 无法自定义请求头
  4. sendBeacon 只能传输 ArrayBufferArrayBufferViewBlobDOMStringFormDataURLSearchParams 类型的数据
  5. 如果处于危险的网络环境,或者开启了广告屏蔽插件 此请求将无效

navigator.sendBeacon 应用场景

  1. 发送心跳包:可以使用 navigator.sendBeacon 发送心跳包,以保持与服务器的长连接,避免因为长时间没有网络请求而导致连接被关闭。
  2. 埋点:可以使用 navigator.sendBeacon 在页面关闭或卸载时记录用户在线时间,pv uv,以及错误日志上报 按钮点击次数。
  3. 发送用户反馈:可以使用 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)
}

后端接收到文件

image-20231105115637566

浏览器相应数据

image-20231105115647565

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 {
        // 不在白名单中,需要验证token
        const 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.body
    console.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 对象

image-20231105203133568

image-20231105203142070

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 way
  var html = filterXSS('<script>alert("xss");</scr' + "ipt>");
  alert(html);
</script>

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

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

相关文章

Unity中Shader的GI的间接光实现

文章目录 前言一、GI中 间接光照的实现1、看Unity的源码可知&#xff0c;在计算GI的间接光照时&#xff0c;最主要的实现是在UnityGI_Base函数中 二、分析 UnityGI_Base 中实现的功能1、ResetUnityGI的作用2、第一个#if中实现的功能&#xff1a;计算在Distance Shadowmask 中实…

网络资料(忘传了)

1网络分层模型和应用协议 1.1分层模型 1.1.1分层的意义 当遇到一个复杂问题的时候&#xff0c;可以使用分层的思想把问题简单化 比如&#xff0c;你有半杯82年的可乐&#xff0c;想分享给你的朋友王富贵&#xff0c;但你们已经10年没有联系了。要完成这件事&#xff0c;你可…

JavaScript引用数据类型(对象类型)和原始(基本)数据类型特点比较

JavaScript引用数据类型&#xff08;对象类型&#xff09;和原始&#xff08;基本&#xff09;数据类型特点比较 为讲解JavaScript引用数据类型&#xff08;对象类型&#xff09;和原始&#xff08;基本&#xff09;数据类型特点比较&#xff0c;需要先回顾JavaScript数据类型…

UE5——源码阅读——3——引擎退出

这边主要是做了个标记&#xff0c;为了UE的性能分析 把全局运行设置为0&#xff0c;把日志也设置为空 判断预加载屏幕 关闭visual logger 关闭资源编译的管理器 引擎预退出 预退出的核心代理 关闭网络追踪 关闭所有电影场景的捕捉接口 关闭UE中用于MID的缓存 关闭引擎…

哆啦百宝箱APP

专门为年轻人设计的APP&#xff0c;主打的免费、无恶心广告、不获取任何个人信息。 哆啦百宝箱 ● 永久免费 ● 无恶心广告 ● 种类巨多 ● 全民参与 ● 爆款功能 ● 用心创造 哆啦百宝箱 提供了从日常、图片、查询、设备、趣味、娱乐等多方面的功能&#xff0c; 操作简单&a…

postMessage

A:端口3000 import React, { useEffect } from react;function App() {useEffect(() > {const childWindow document.getElementById(child).contentWindow;const sendMessageToChild () > {childWindow.postMessage("主页面消息", "http://localhost:…

Java 数据结构篇-实现单链表核心API

&#x1f525;博客主页&#xff1a; 小扳_-CSDN博客 ❤感谢大家点赞&#x1f44d;收藏⭐评论✍ 文章目录 1.0 单链表的说明 2.0 单链表的创建 2.1 单链表 - 头插节点 2.2 单链表 - 遍历 2.2.1 使用简单的 for/while 循环 2.2.2 实现 forEach 方法 2.2.3 实现迭代器的方法 2.…

使用腾讯云服务器建站流程(新手站长指南)

使用腾讯云服务器搭建网站全流程&#xff0c;包括轻量应用服务器和云服务器CVM建站教程&#xff0c;轻量可以使用应用镜像一键建站&#xff0c;云服务器CVM可以通过安装宝塔面板的方式来搭建网站&#xff0c;腾讯云服务器网txyfwq.com分享使用腾讯云服务器建站教程&#xff0c;…

【网络协议】聊聊CND如何进行提升系统读性能

我们知道对于京东这种仓储来说&#xff0c;其实并不是在北京有一个仓储中心&#xff0c;而是针对全国主要的地方&#xff0c;北京、上海、广州、杭州&#xff0c;郑州等地方都有自己的仓储中心&#xff0c;当用户下单后&#xff0c;就会根据最近的仓储进行发货&#xff0c;不仅…

第二章:input partitioning

文章目录 Input partitioninginput partitioning 的目的computational / domain faults等价类&#xff08;equivalence classes&#xff09;input conditions & valid / invalid inputspartitioning and equivalence classes等价类划分的原则 白盒 - Domain testing复合谓词…

curl(七)上传和下载

一 上传 ① -T | --upload 上传 ​1、向ftp服务器 传一个文件&#xff1a;curl -T localfile -u name&#xff1a;passwd ftp://upload_site&#xff1a;port/path/2、向http服务器上传文件curl -T localfile http://www.wzj.com/wzj.html注意: 这时候使用的协议是HTTP的PUT…

全球首款双模型AI手机METAVERTU2,为用户开发“第二大脑”

在2023年11月1日&#xff0c;英国奢侈手机品牌VERTU在香港举办了一场新品发布会&#xff0c;它推出了一款全新的AI手机称为METAVERTU2&#xff0c;这是全球首款双模型AI手机。此款手机将Web3技术与人工智能相结合&#xff0c;通过AI模型标记数据和AI Agent的方式&#xff0c;将…

在线安装Arthas以及常用命令介绍

Arthas介绍&#xff1a;arthas(阿尔萨斯)是阿里巴巴开源的一款 Java 诊断工具&#xff0c;它可以对运行中的 Java 程序进行实时监控和故障排查。Arthas 提供了丰富的功能&#xff0c;如线程分析、内存分析、类加载分析等&#xff0c;帮助开发者快速定位问题并提高开发效率。 主…

自动控制原理答案

题目 现有一个单位反馈系统的开环传递函数为 试对该系统进行以下分析。 1.基础分析 计算该系统的闭环传递函数。 2.稳定性分析 2.1 使用劳斯判据分析该系统的稳定性 2.2 使用MATLAB编程&#xff0c;计算该系统有关于稳定性分析的零、极点&#xff0c;分析其稳定性。 3.暂态性…

性能测试知多少---吞吐量

我们每天的生活中都在用水用电&#xff0c;我只会关心自己的水管是否有水&#xff0c;水压是否稳定&#xff0c;如果我们把水龙头拧到最大&#xff0c;还是一滴一滴的流水。那我们就要愤怒了&#xff0c;直接找房东问明情况。我们从来没想过去找自来水公司。我们每天都会上网&a…

【原创】java+swing+mysql宠物领养管理系统设计与实现

摘要&#xff1a; 生活中&#xff0c;有很多被人遗弃的宠物&#xff0c;这些宠物的处理成为了一个新的难题。生活中也有许多人喜欢养宠物&#xff0c;为了方便大家进行宠物领养&#xff0c;提高宠物领养管理的效率和便利性。本文针对这一问题&#xff0c;提出设计和实现一个基…

Matlab上机三(Apriori算法)

1、题目要求 &#xff08;1&#xff09; 读取给定的交易数据库test3.txt&#xff0c;将整个交易数据库表示为一个矩阵&#xff0c;每个元组表示成一个行向量&#xff0c;向量长度为4。其中&#xff0c;一个项目出现在这个元组中&#xff0c;则相应位置设为1&#xff0c;否则为…

比亚迪被曝 24 小时收到 12 万份简历?

众所周知&#xff0c;今年找工作的难度都相当大&#xff0c;不论是应届毕业生还是经验丰富的职场人士&#xff0c;都面临相同的困境。然而&#xff0c;没想到情况居然如此糟糕&#xff0c;着实让人震惊。 最近&#xff0c;比亚迪公司被曝收到了12万份简历&#xff0c;简历投递…

深度学习框架TensorFlow.NET环境搭建1(C#)

测试环境 visual studio 2017 window10 64位 测试步骤如下&#xff1a; 1 新建.net framework控制台项目&#xff0c;工程名称为TensorFlowNetDemo&#xff0c;.net framework的版本选4.7.2&#xff0c;如下图&#xff1a; 2 分别安装TensorFlow.NET包(先装)和SciSharp.…