国产亚洲精品福利在线无卡一,国产精久久一区二区三区,亚洲精品无码国模,精品久久久久久无码专区不卡

當(dāng)前位置: 首頁 > news >正文

優(yōu)化方案數(shù)學(xué)2023版電子版seo中文意思

優(yōu)化方案數(shù)學(xué)2023版電子版,seo中文意思,亞馬遜aws永久免費(fèi)服務(wù)器,馬鞍山網(wǎng)站建設(shè)網(wǎng)絡(luò)請求 node編寫接口 這里用到的幾個(gè)包的作用 express:基于 Node.js 平臺(tái),快速、開放、極簡的 Web 開發(fā)框架,官網(wǎng):https://www.expressjs.com.cn/cors:用來解決跨域問題body-parser:可以通過 req.body…

網(wǎng)絡(luò)請求

node編寫接口

這里用到的幾個(gè)包的作用

  • express:基于 Node.js 平臺(tái),快速、開放、極簡的 Web 開發(fā)框架,官網(wǎng):https://www.expressjs.com.cn/
  • cors:用來解決跨域問題
  • body-parser:可以通過 req.body 獲取post請求傳遞過來的json數(shù)據(jù)
  • 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())
// 設(shè)置上傳目錄和文件名
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參數(shù)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// 設(shè)置每隔20毫秒主動(dòng)發(fā)送一次數(shù)據(jù)let timer = setInterval(()=>{if(current >= arr.length){clearInterval(timer)}else{// 發(fā)送消息必須是 data: 開頭,\n\n 結(jié)尾。中間是發(fā)送的內(nèi)容,內(nèi)容必須是一個(gè)字符串res.write(`data:${arr[current]}\n\n`)current++}},20)
})app.listen(10086, () =>{console.log("啟動(dòng)成功: http://localhost:10086")
})

Ajax請求

發(fā)送GET請求

let xhr = new XMLHttpRequest()
function sendGet(){xhr.open("GET","http://127.0.0.1:10086/name")// 當(dāng)接口相應(yīng)數(shù)據(jù)后會(huì)觸發(fā)onload回調(diào)xhr.onload = function (){if(xhr.status === 200){console.log(JSON.parse(xhr.responseText))}}xhr.send()
}

發(fā)送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))}}// 定義發(fā)送給后端的數(shù)據(jù)let data = {name:"張三",age:18}// 把數(shù)據(jù)放在send中進(jìn)行發(fā)送,需要使用JSON.stringify進(jìn)行序列化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

設(shè)置超時(shí)時(shí)間

function sendGet() {xhr.open("GET", "http://127.0.0.1:10086/name")xhr.setRequestHeader("Content-Type", "application/json")// 設(shè)置超時(shí)時(shí)間1000毫秒xhr.timeout = 1000xhr.addEventListener("timeout", function () {console.log("請求超時(shí)")})xhr.onload = function () {if (xhr.status === 200) {console.log(JSON.parse(xhr.responseText))}}xhr.send()
}

請求中斷

xhr.abort()
// 請求中斷回調(diào)
xhr.addEventListener("abort",function (){console.log("請求中斷")
})

監(jiān)聽上傳進(jìn)度

// 監(jiān)聽上傳進(jìn)度
xhr.addEventListener("progress",function (event){console.log(`${(event.loaded / event.total * 100).toFixed(2)}%`)
})

Axios使用

Axios 是對 Ajax 的封裝,可以幫助我們更好的發(fā)送請求,官方文檔:http://www.axios-js.com/zh-cn/docs/

下面是分別發(fā)送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是一種網(wǎng)絡(luò)通信協(xié)議,用于在客戶端和服務(wù)器之間傳輸數(shù)據(jù)。該協(xié)議使用HTTP請求和響應(yīng)進(jìn)行通信,與傳統(tǒng)的AJAX方式相比,Fetch更加簡單易用,并提供了許多現(xiàn)代化的功能。

使用Fetch可以方便地向服務(wù)器發(fā)送請求,并將響應(yīng)返回給客戶端。你可以使用Fetch獲取文本、JSON、圖像和文件等數(shù)據(jù),并進(jìn)行各種處理。Fetch還支持流式傳輸和取消請求等高級功能,使得處理大型數(shù)據(jù)集和長時(shí)間運(yùn)行的操作變得更加簡單和可靠。

Fetch API也是Javascript中常用的API之一,它提供了一組方法和屬性,可以在瀏覽器端與服務(wù)器進(jìn)行通信。通過Fetch API,你可以輕松地使用Fetch協(xié)議進(jìn)行數(shù)據(jù)傳輸,并對請求和響應(yīng)進(jìn)行操作和處理。

fetch 對比 xhr

fetchXMLHttpRequest(XHR)都是前端與服務(wù)器進(jìn)行數(shù)據(jù)交互的常用方式,它們各有優(yōu)缺點(diǎn),下面是它們的比較:

  1. API 設(shè)計(jì)和使用方式

fetch 的 API 設(shè)計(jì)更加現(xiàn)代化、簡潔和易于使用,使用起來更加直觀和方便。相比之下,XHR 的 API 設(shè)計(jì)比較繁瑣,需要進(jìn)行多個(gè)參數(shù)的配置和回調(diào)函數(shù)的處理。

  1. 支持的請求方法

fetch API 默認(rèn)只支持 GET 和 POST 請求方法,而 XHR 則支持所有標(biāo)準(zhǔn)的 HTTP 請求方法。

  1. 請求頭部

fetch 中設(shè)置請求頭部的方式更加清晰和直接,可以通過 Headers 對象進(jìn)行設(shè)置,而 XHR 的方式相對較為繁瑣。

  1. 請求體

在發(fā)送 POST 請求時(shí),fetch API 要求將請求體數(shù)據(jù)作為參數(shù)傳遞給 fetch 方法中的 options 對象,而 XHR 可以直接在 send() 方法中設(shè)置請求體數(shù)據(jù)。

  1. 支持的數(shù)據(jù)類型

在解析響應(yīng)數(shù)據(jù)時(shí),fetch API 提供了多種方法,包括 .json(), .blob(), .arrayBuffer() 等,而 XHR 只支持文本和二進(jìn)制數(shù)據(jù)兩種數(shù)據(jù)類型。

  1. 跨域請求

在進(jìn)行跨域請求時(shí),fetch API 提供了一種簡單而強(qiáng)大的解決方案——使用 CORS(跨域資源共享)頭部實(shí)現(xiàn)跨域請求,而 XHR 則使用了一個(gè)叫做 XMLHttpRequest Level 2 的規(guī)范,在代碼編寫上相對較為繁瑣。

總的來說,fetch API 與 XHR 各有優(yōu)缺點(diǎn),具體選擇哪種方式還需要根據(jù)具體情況進(jìn)行考慮。平時(shí)開發(fā)中使用較多的是 fetch ,因?yàn)樗褂梅奖?、API 簡潔、語法清晰,同時(shí)也支持了大多數(shù)常用的功能,可以有效地簡化前端開發(fā)流程。

fetch 返回格式

  1. text(): 將響應(yīng)體解析為純文本字符串并返回。
  2. json(): 將響應(yīng)體解析為JSON格式并返回一個(gè)JavaScript對象。
  3. blob(): 將響應(yīng)體解析為二進(jìn)制數(shù)據(jù)并返回一個(gè)Blob對象。
  4. arrayBuffer(): 將響應(yīng)體解析為二進(jìn)制數(shù)據(jù)并返回一個(gè)ArrayBuffer對象。
  5. formData(): 將響應(yīng)體解析為FormData對象。

發(fā)送GET請求

function fetchGet() {fetch("http://localhost:10086/name").then(res => res.json()).then(res => {console.log(res)})
}

發(fā)送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 構(gòu)造器

<button onclick="fetchGet()">get請求</button>
<button onclick="stop()">終止請求</button>

發(fā)送請求

const abort = new AbortController()
function fetchGet() {fetch("http://localhost:10086/name",{signal:abort.signal}).then(res => res.json()).then(res => {console.log(res)})
}

調(diào)用終止方法

function stop(){abort.abort()
}

請求超時(shí)

fetch 本身沒有超時(shí)定義,需要我們自己封裝一個(gè)計(jì)時(shí)器,到時(shí)間后調(diào)用 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)是一種用于實(shí)現(xiàn)服務(wù)器主動(dòng)向客戶端推送數(shù)據(jù)的技術(shù),也被稱為“事件流”(Event Stream)。它基于 HTTP 協(xié)議,利用了其長連接特性,在客戶端與服務(wù)器之間建立一條持久化連接,并通過這條連接實(shí)現(xiàn)服務(wù)器向客戶端的實(shí)時(shí)數(shù)據(jù)推送。

SSE 和 Socket 區(qū)別

SSE(Server-Sent Events)和 WebSocket 都是實(shí)現(xiàn)服務(wù)器向客戶端實(shí)時(shí)推送數(shù)據(jù)的技術(shù),但它們在某些方面還是有一定的區(qū)別。

  1. 技術(shù)實(shí)現(xiàn)

SSE 基于 HTTP 協(xié)議,利用了其長連接特性,通過瀏覽器向服務(wù)器發(fā)送一個(gè) HTTP 請求,建立一條持久化的連接。而 WebSocket 則是通過特殊的升級協(xié)議(HTTP/1.1 Upgrade 或者 HTTP/2)建立新的 TCP 連接,與傳統(tǒng) HTTP 連接不同。

  1. 數(shù)據(jù)格式

SSE 可以傳輸文本和二進(jìn)制格式的數(shù)據(jù),但只支持單向數(shù)據(jù)流,即只能由服務(wù)器向客戶端推送數(shù)據(jù)。WebSocket 支持雙向數(shù)據(jù)流,客戶端和服務(wù)器可以互相發(fā)送消息,并且沒有消息大小限制。

  1. 連接狀態(tài)

SSE 的連接狀態(tài)僅有三種:已連接、連接中、已斷開。連接狀態(tài)是由瀏覽器自動(dòng)維護(hù)的,客戶端無法手動(dòng)關(guān)閉或重新打開連接。而 WebSocket 連接的狀態(tài)更靈活,可以手動(dòng)打開、關(guān)閉、重連等。

  1. 兼容性

SSE 是標(biāo)準(zhǔn)的 Web API,可以在大部分現(xiàn)代瀏覽器和移動(dòng)設(shè)備上使用。但如果需要兼容老版本的瀏覽器(如 IE6/7/8),則需要使用 polyfill 庫進(jìn)行兼容。而 WebSocket 在一些老版本 Android 手機(jī)上可能存在兼容性問題,需要使用一些特殊的 API 進(jìn)行處理。

  1. 安全性

SSE 的實(shí)現(xiàn)比較簡單,都是基于 HTTP 協(xié)議的,與普通的 Web 應(yīng)用沒有太大差異,因此風(fēng)險(xiǎn)相對較低。WebSocket 則需要通過額外的安全措施(如 SSL/TLS 加密)來確保數(shù)據(jù)傳輸?shù)陌踩?#xff0c;避免被竊聽和篡改,否則可能會(huì)帶來安全隱患。

總體來說,SSE 和 WebSocket 都有各自的優(yōu)缺點(diǎn),適用于不同的場景和需求。如果只需要服務(wù)器向客戶端單向推送數(shù)據(jù),并且應(yīng)用在前端的瀏覽器環(huán)境中,則 SSE 是一個(gè)更加輕量級、易于實(shí)現(xiàn)和維護(hù)的選擇。而如果需要雙向傳輸數(shù)據(jù)、支持自定義協(xié)議、或者在更加復(fù)雜的網(wǎng)絡(luò)環(huán)境中應(yīng)用,則 WebSocket 可能更加適合。

適用于場景

chatGPT 返回的數(shù)據(jù) 就是使用的SSE 技術(shù)

實(shí)時(shí)數(shù)據(jù)大屏 如果只是需要展示 實(shí)時(shí)的數(shù)據(jù)可以使用SSE技術(shù) 而不是非要使用webSocket

使用

調(diào)用node端寫好的 sse 接口,這個(gè)接口會(huì)每隔20毫秒主動(dòng)向前端發(fā)送一次數(shù)據(jù)

<!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()">關(guān)閉</button>
</body>
<script>let sse = nullfunction start(){sse = new EventSource("http://localhost:10086/ssh")// 鏈接成功回調(diào)sse.onopen = ()=>{console.log("open")}// 監(jiān)聽消息sse.onmessage = (event)=>{console.log(event)// 默認(rèn)監(jiān)聽message,這個(gè)可以定義// 默認(rèn)數(shù)據(jù)也是在event的data屬性中返回document.getElementById("message").innerHTML += event.data}// 鏈接失敗回調(diào)sse.onerror = ()=>{console.log("onerror")}}function close(){console.log("關(guān)閉")sse.close()}
</script>
</html>

WebSocket

WebSocket是雙向通信,客戶端可以隨時(shí)向服務(wù)端發(fā)送消息,反過來服務(wù)端也可以隨時(shí)向客戶端發(fā)送消息

雙向通信

使用node定義接口

安裝

npm install ws

編寫接口

const ws = require("ws")// 創(chuàng)建服務(wù)
const wss = new ws.Server({port:8888},()=>{console.log("socket服務(wù)啟動(dòng)成功")
})// 監(jiān)聽鏈接成功提示
wss.on("connection",(socket)=>{console.log("客戶端鏈接成功")socket.on("message",e=>{// 通過e.toString()獲取前端傳遞過來的東西socket.send("我是服務(wù)器,我收到你的消息了,內(nèi)容是:"+ e.toString())})
})

調(diào)用

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><title>Title</title>
</head>
<body>
<input type="text" id="msg"/>
<button onclick="send()">發(fā)送</button>
<ul id="ul"></ul>
</body>
<script>let msg = document.querySelector("#msg")let ul = document.querySelector("#ul")// 鏈接let wss = new WebSocket("ws://localhost:8888")// 監(jiān)聽消息wss.addEventListener("message", e => {console.log(e.data)let li = document.createElement("li")li.innerText = e.dataul.appendChild(li)})function send() {// 發(fā)送消息wss.send(msg.value)msg.value = ""}
</script>
</html>

消息廣播

默認(rèn)一個(gè)鏈接只會(huì)收到自己與服務(wù)器之間的消息,不能收到其他鏈接接收的消息,我們通過如下方式來實(shí)現(xiàn)

// 監(jiān)聽鏈接成功提示
wss.on("connection",(socket)=>{console.log("客戶端鏈接成功")socket.on("message",e=>{// 廣播消息 wss.clients 存放了所有鏈接信息,遍歷這個(gè)鏈接信息,給所有鏈接者發(fā)送消息wss.clients.forEach(client=>{// 通過e.toString()獲取前端傳遞過來的東西client.send("我是服務(wù)器,我收到你的消息了,內(nèi)容是:"+ e.toString())})})
})

心跳檢測

在長時(shí)間沒有發(fā)送消息交互,或者網(wǎng)絡(luò)不好的情況下,websocket 會(huì)出現(xiàn)斷掉的情況,我們可以通過心跳檢測的機(jī)制,定時(shí)發(fā)送一次消息,實(shí)現(xiàn)鏈接保活

const ws = require("ws")// 創(chuàng)建服務(wù)
const wss = new ws.Server({port: 8888}, () => {console.log("socket服務(wù)啟動(dòng)成功")
})// 消息類型
const STATE = {HEART:1,MESSAGE:2
}// 監(jiān)聽鏈接成功提示
wss.on("connection", (socket) => {console.log("客戶端鏈接成功")socket.on("message", e => {// 廣播消息wss.clients.forEach(client => {// 通過e.toString()獲取前端傳遞過來的東西client.send(JSON.stringify({type:STATE.MESSAGE,data:"我是服務(wù)器,我收到你的消息了,內(nèi)容是:" + 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)
})

同時(shí)前端需要區(qū)分不同的消息類型

// 監(jiān)聽消息
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 實(shí)現(xiàn)高效的數(shù)據(jù)上報(bào)

在 web 開發(fā)中,我們經(jīng)常需要將用戶行為或性能數(shù)據(jù)上報(bào)到服務(wù)器。為了不影響用戶體驗(yàn),開發(fā)者通常會(huì)在頁面卸載時(shí)進(jìn)行數(shù)據(jù)上報(bào)。然而,傳統(tǒng)的數(shù)據(jù)上報(bào)方式,如 XMLHttpRequestFetch API,容易受到頁面卸載過程中的阻塞,導(dǎo)致數(shù)據(jù)丟失。為了解決這個(gè)問題,navigator.sendBeacon API 被引入,它可以在頁面卸載時(shí)安全、可靠地發(fā)送數(shù)據(jù)。

navigator.sendBeacon 對比 Ajax fetch

優(yōu)點(diǎn)

  1. 不受頁面卸載過程的影響,確保數(shù)據(jù)可靠發(fā)送。
  2. 異步執(zhí)行,不阻塞頁面關(guān)閉或跳轉(zhuǎn)。
  3. 能夠發(fā)送跨域請求。

缺點(diǎn)

  1. fetch 和 ajax 都可以發(fā)送任意請求 而 sendBeacon 只能發(fā)送POST
  2. fetch 和 ajax 可以傳輸任意字節(jié)數(shù)據(jù) 而 sendBeacon 只能傳送少量數(shù)據(jù)(64KB 以內(nèi))
  3. fetch 和 ajax 可以定義任意請求頭 而 sendBeacon 無法自定義請求頭
  4. sendBeacon 只能傳輸 ArrayBuffer、ArrayBufferViewBlob、DOMStringFormDataURLSearchParams 類型的數(shù)據(jù)
  5. 如果處于危險(xiǎn)的網(wǎng)絡(luò)環(huán)境,或者開啟了廣告屏蔽插件 此請求將無效

navigator.sendBeacon 應(yīng)用場景

  1. 發(fā)送心跳包:可以使用 navigator.sendBeacon 發(fā)送心跳包,以保持與服務(wù)器的長連接,避免因?yàn)殚L時(shí)間沒有網(wǎng)絡(luò)請求而導(dǎo)致連接被關(guān)閉。
  2. 埋點(diǎn):可以使用 navigator.sendBeacon 在頁面關(guān)閉或卸載時(shí)記錄用戶在線時(shí)間,pv uv,以及錯(cuò)誤日志上報(bào) 按鈕點(diǎn)擊次數(shù)。
  3. 發(fā)送用戶反饋:可以使用 navigator.sendBeacon 發(fā)送用戶反饋信息,如用戶意見、bug 報(bào)告等,以便進(jìn)行產(chǎn)品優(yōu)化和改進(jìn)

其他注意事項(xiàng) type

ping請求 是html5 新增的 并且是sendBeacon 特有的 ping 請求 只能攜帶少量數(shù)據(jù),并且不需要等待服務(wù)端響應(yīng),因此非常適合做埋點(diǎn)統(tǒng)計(jì),以及日志統(tǒng)計(jì)相關(guān)功能。

使用方法

編寫一個(gè)接口

const multer = require("multer");app.post("/ping",multer().none(),(req,res)=>{console.log(req.body.data)res.send("ok")
})

前端發(fā)送 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

瀏覽器相應(yīng)數(shù)據(jù)

image-20231105115647565

JWT鑒權(quán)

首先安裝相關(guān)依賴

npm install jsonwebtoken express cors
  • jsonwebtoken:用于生成token和驗(yàn)證token
  • cors:處理跨域問題

接口編寫

const express = require("express")
const cors = require("cors")
const jwt = require("jsonwebtoken")
const app = express()// 處理跨域問題
app.use(cors())
// 可以使用 req.body 獲取post請求傳遞的json數(shù)據(jù)
app.use(express.json())
// token加鹽
const KEY = "123456"// 白名單,包含不需要驗(yàn)證token的路徑
const whitelist = ['/login'];
// 驗(yàn)證token的中間件
app.use((req, res, next) => {// 檢查路徑是否在白名單中if (whitelist.includes(req.path)) {console.log("3333")// 在白名單中,直接進(jìn)入下一個(gè)中間件或請求處理函數(shù)next();} else {// 不在白名單中,需要驗(yàn)證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,第一個(gè)參數(shù)是token攜帶的內(nèi)容,第二是KEY,第三個(gè)是過期時(shí)間token:jwt.sign({id:1,name:data.name}, KEY, {expiresIn: "1h"})})}else{res.send({code:500,msg:"用戶名或密碼錯(cuò)誤"})}
})// 獲取集合信息
app.get("/list",(req,res)=>{res.send([{name:"lisi",age:1},{name:"wangwu",age:2},])
})app.listen(3000, () => {console.log("服務(wù)啟動(dòng)成功:http://localhost:3000")
})

前端調(diào)用

前端在發(fā)送請求時(shí)需要在請求頭中攜帶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>

判斷網(wǎng)絡(luò)狀態(tài)

獲取是否聯(lián)網(wǎng)

// 是否聯(lián)網(wǎng),返回true或者false,true表示已經(jīng)聯(lián)網(wǎng),false表示沒有聯(lián)網(wǎng)
console.log(navigator.onLine)

獲取網(wǎng)絡(luò)環(huán)境

前端還可以判斷用戶當(dāng)前所在網(wǎng)絡(luò)的好壞

// 獲取網(wǎng)絡(luò)環(huán)境
console.log(navigator.connection)

返回的是一個(gè) NetworkInformation 對象

image-20231105203133568

image-20231105203142070

XSS跨站腳本攻擊

隨著互聯(lián)網(wǎng)的快速普及,越來越多的敏感信息被存儲(chǔ)在網(wǎng)絡(luò)上,例如個(gè)人身份信息、財(cái)務(wù)信息等。在當(dāng)前數(shù)字化時(shí)代,這些安全問題變得更加突出。作為開發(fā)者,我們必須采取適當(dāng)?shù)姆婪洞胧?#xff0c;以確保用戶數(shù)據(jù)的安全性。本文將著重探討跨站腳本攻擊(Cross-site scripting,XSS)這一常見的網(wǎng)絡(luò)攻擊方式,包括其定義、原理、危害、分類和防范措施,以幫助大家更好地預(yù)防此類安全風(fēng)險(xiǎn)。

概述

**定義:**跨站點(diǎn)腳本攻擊,簡稱XSS,是指攻擊者利用網(wǎng)站存在的漏洞,通過在網(wǎng)站中注入惡意腳本代碼,從而使得用戶在訪問該網(wǎng)站時(shí)受到攻擊。這些惡意腳本代碼通常是JavaScript 代碼,它們可以竊取用戶的敏感信息,如用戶名、密碼等,并將這些信息發(fā)送到攻擊者的服務(wù)器。

原理

XSS攻擊的本質(zhì)是利用Web應(yīng)用程序中的漏洞,向網(wǎng)頁注入惡意腳本代碼,然后將這些代碼嵌入到網(wǎng)頁中,當(dāng)其他用戶訪問這個(gè)網(wǎng)頁時(shí),惡意腳本將會(huì)被執(zhí)行。

攻擊者通常會(huì)在Web應(yīng)用程序的輸入框、評論框、搜索框等可輸入內(nèi)容的地方輸入特定的腳本代碼,這些代碼可以被Web應(yīng)用程序直接插入到網(wǎng)頁中,導(dǎo)致網(wǎng)頁上的所有用戶都會(huì)受到攻擊。

XSS攻擊的原理包括以下幾個(gè)步驟:

1、攻擊者在Web應(yīng)用程序的輸入框、評論框等可輸入內(nèi)容的地方輸入包含script標(biāo)簽的惡意腳本代碼,例如:

<script>
// 在這里插入惡意腳本代碼
</script>

2、Web應(yīng)用程序?qū)阂饽_本代碼保存到數(shù)據(jù)庫中或直接將其插入到網(wǎng)頁的HTML代碼中。

3、當(dāng)其他用戶訪問這個(gè)網(wǎng)頁時(shí),瀏覽器會(huì)執(zhí)行其中的惡意腳本代碼。惡意腳本可以竊取用戶的敏感信息,如登錄憑證、瀏覽器歷史記錄、Cookie等,或者通過控制用戶的瀏覽器來進(jìn)行更多的攻擊。

例如,以下是一段可以竊取用戶Cookie的惡意腳本代碼:

<script>
let cookieValue = document.cookie;
// 將cookieValue發(fā)送到攻擊者的服務(wù)器
</script>

4、攻擊者獲取到用戶的敏感信息后,可以進(jìn)行更進(jìn)一步的攻擊,例如重定向到惡意網(wǎng)站、發(fā)起釣魚攻擊等。

預(yù)防工具

使用第三方庫來預(yù)防,這里使用 xss,官網(wǎng)文檔: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>
http://aloenet.com.cn/news/44636.html

相關(guān)文章:

  • 免費(fèi)域名網(wǎng)站搭建seo排名軟件
  • 口碑好的合肥網(wǎng)站建設(shè)重慶百度推廣電話
  • 引擎網(wǎng)站推廣法怎么做google下載app
  • 網(wǎng)站建設(shè)常規(guī)自適應(yīng)信息流廣告優(yōu)化師
  • 網(wǎng)站建設(shè)中的html頁面seo網(wǎng)站優(yōu)化培訓(xùn)
  • 2018年網(wǎng)站建設(shè)做搜索引擎推廣多少錢
  • 網(wǎng)站建站客戶需求表單鄭州網(wǎng)站制作選擇樂云seo
  • 做網(wǎng)站最主要是什么招聘seo專員
  • 建設(shè)銀行澳洲招聘網(wǎng)站最新足球消息
  • 禪城網(wǎng)站建設(shè)報(bào)價(jià)it培訓(xùn)課程
  • wordpress文件的完整url地址seo是什么意思啊
  • 響應(yīng)式網(wǎng)站的制作網(wǎng)站制作百度大數(shù)據(jù)查詢平臺(tái)
  • 貴陽網(wǎng)站推廣網(wǎng)絡(luò)營銷策劃推廣方案
  • cad培訓(xùn)班一般學(xué)費(fèi)多少深圳網(wǎng)站設(shè)計(jì)專家樂云seo
  • c語言除了做網(wǎng)站還能干什么廣州疫情升級
  • 網(wǎng)站建設(shè)公司六安網(wǎng)站seo方案
  • 龍巖網(wǎng)站建設(shè)全包sem和seo是什么職業(yè)
  • 中企動(dòng)力做過的網(wǎng)站女教師遭網(wǎng)課入侵視頻
  • wordpress獲取當(dāng)前目錄父目錄id吉林seo管理平臺(tái)
  • 縣文化館網(wǎng)站建設(shè)方案市場調(diào)研報(bào)告1000字
  • 哪些網(wǎng)站做ip向小說神秘網(wǎng)站
  • 央視新聞seo的五個(gè)步驟
  • 尋找徐州網(wǎng)站開發(fā)企業(yè)網(wǎng)絡(luò)營銷青島
  • 深圳廣告公司前十強(qiáng)seo簡單速排名軟件
  • 單頁網(wǎng)站在線制作公司搜索seo
  • 做網(wǎng)站上哪買空間鄭州seo顧問外包公司
  • 書畫網(wǎng)站模板下載跨境電商seo什么意思
  • 網(wǎng)絡(luò)營銷的方法包括哪些重慶seo是什么
  • wordpress 子主題路由seo沒什么作用了
  • 素材網(wǎng)站源碼成品視頻直播軟件推薦哪個(gè)好一點(diǎn)