# HTTP 协议请求报文、响应

一个 HTTP 请求报文可以由请求行、请求头、空行和请求体 4 个部分组成。
一个 HTTP 响应报文是由响应行、响应头、空行和响应体 4 个部分组成。
(报文 (message) 是网络中交换与传输的数据单元)

https://zhuanlan.zhihu.com/p/533284035 (超详细的 HTTP 协议请求报文、响应报文教程)

#

# JSON

# 什么是 json

JSON 是一种轻量级的数据交互格式。可以按照 JSON 指定的格式去组织和封装数据

JSON 本质上是一个带有特定格式的字符串

主要功能:json 就是一种在各个编程语言中流通的数据格式,负责不同编程语言中的数据传递和交互。类似于:
国际通用语言 - 英语
中国 56 个民族不同地区的通用语言 - 普通话

# json 有什么用

各种编程语言存储数据的容器不尽相同,在 Python 中有字典 dict 这样的数据类型,而其它语言可能没有对应的字典。
为了让不同的语言都能够相互通用的互相传递数据,JSON 就是一种非常良好的中转数据格式。

# json 格式数据转化

# json数据的格式可以是: 
{"name":"admin","age":18}{}括起来的键值对
# 也可以是:  
[{"name":"admin","age":18},{"name":"root","age":16},{"name":"张三","age":20}] 
[]括起来的元素
可以嵌套
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>2.0.39</version>
        </dependency>

Java 中:java 转 json 字符串

String jsonStr = JSON.toJSONString(objs);

JS 中:json 字符串转 JavaScript 对象

JSON.parse(this.responseText)

#

# Ajax

Ajax(Asynchronous JavaScript And XML)即异步 JavaScript 和 XML,是一组用于在网页上进行异步数据交换的 Web 开发技术,可以在不刷新整个页面的情况下向服务器发起请求并获取数据,然后将数据插入到网页中的某个位置。这种技术能够实现增量式更新页面,提高用户交互体验,减少响应时间和带宽的消耗。

# 优点

  • 提升用户体验(通过减少页面的重载和刷新,使得网站变得更加灵活和的动态)
  • 减轻服务器压力(通过 Ajax 可以有效减少服务器接收到的请求次数和需要响应的数据量)
  • 提高响应速度(异步获得数据并更新页面)
  • 增加交互性(页面变得动态性和交互性)

# 缺点

  • Ajax 对 SEO(搜索引擎优化不友好)
  • 使用 Ajax 时,需要考虑数据安全性和网络安全性,并采取相应的措施防范

#

# XMLHttpRequest

# 使用

使用 XMLHttpRequest 可以通过 JavaScript 发起 HTTP 请求,接收来自服务器的响应,并动态地更新网页中的内容。这种异步通信方式不会阻塞用户界面,有利于增强用户体验。

// 发送 get 请求
const xhr = new XMLHttpRequest();
xhr.open('GET', 'http://localhost:3000/api/txt')
xhr.onload = function() {
  if (xhr.status === 200) {
        document.querySelector('#result').innerText = xhr.responseText;
    }
    else {
       console.log('Request failed.  Returned status of ' + xhr.status);
   }
};
xhr.send(null);
// 发送 post 请求
const xhr = new XMLHttpRequest();
xhr.open('POST', 'http://localhost:3000/api/post')
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.onload = function() {
  if (xhr.status === 200) {
        document.querySelector('#result').innerText = xhr.responseText;
    }
    else {
       console.log('Request failed.  Returned status of ' + xhr.status);
   }
};
xhr.send(JSON.stringify({name: 'zhangsan', age: 18}));

# 中断请求

xhr 通过 addEventListener 事件监听的机制来进行请求的中断和超时处理。

xhr.addEventListener('abort', function (event) {
    console.log('我被中断了');
});

# 超时时间

xhr.addEventListener('timeout', function (event) {
     console.log('超时啦');
});

# 监听进度

xhr 中的监听进度可以获得全过程的进行进度,这是 fetch 这个 api 所没有的

xhr.addEventListener('progress', function (event) {
document.querySelector('#progress').innerText = `${(event.loaded / event.total * 100).toFixed(2)}%`;
});

#

# Fetch

# 使用

fetch 返回格式:

  • text (): 将响应体解析为纯文本字符串并返回。

  • json (): 将响应体解析为 JSON 格式并返回一个 JavaScript 对象。

  • blob (): 将响应体解析为二进制数据并返回一个 Blob 对象。

  • arrayBuffer (): 将响应体解析为二进制数据并返回一个 ArrayBuffer 对象。

  • formData (): 将响应体解析为 FormData 对象。

//get 请求
fetch('http://localhost:3000/api/txt').then(res => {
    console.log(res);
    return res.text()
}).then(res => {
    console.log(res);
})
//post 请求
fetch('http://localhost:3000/api/post',{
    method:'POST',
    headers:{
        'Content-Type':'application/json'
    },
    body:JSON.stringify({
        name:'zhangsan',
        age:18
    })
}).then(res => {
    console.log(res);
    return res.json()
}).then(res => {
    console.log(res);
})

# 中断请求

使用 AbortControllerabort 方法中断

const abort = new AbortController()
fetch('http://localhost:3000/api/post',{
    method:'POST',
    headers:{
        'Content-Type':'application/json'
    },
    signal:abort.signal,
    body:JSON.stringify({
        name:'zhangsan',
        age:18
    })
}).then(res => {
    console.log(res);
    return res.json()
}).then(res => {
    console.log(res);
})
document.querySelector('#stop').addEventListener('click', () => {
        console.log('stop');
        abort.abort()
})

# 获取进度

使用 data.clone () 方法复制了响应对象 data,然后使用 getReader () 方法获取数据流中的 reader 对象,接着通过读取数据流并计算已加载字节数,实现了一个基于原生 JavaScript 的进度条功能。

const btn = document.querySelector('#send')
const sendFetch = async () => {
    const data = await fetch('http://localhost:3000/api/txt',{
        signal:abort.signal
    })
    //fetch 实现进度条
    const response = data.clone()
    const reader = data.body.getReader()
    const contentLength = data.headers.get('Content-Length')
    let loaded = 0
    while (true) {
        const { done, value } = await reader.read()
        if (done) {
            break
        }
        loaded += value?.length || 0;
        const progress = document.querySelector('#progress')
        progress.innerHTML = (loaded / contentLength * 100).toFixed(2) + '%'
    }
    const text = await response.text()
    console.log(text);
}
btn.addEventListener('click', sendFetch)

# 携带 cookie

const data = await fetch('http://localhost:3000/api/txt',{
    signal:abort.signal,
    //cookie
    credentials:'include',
})

# Fetch 和 XMLHTTPRequest 对比

fetchXMLHttpRequest (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 简洁、语法清晰,同时也支持了大多数常用的功能,可以有效地简化前端开发流程。

#

# axios

专注与网络请求的库
相比于原生的 XMLHttpRequest 对象,axios 简单易用
相比与 jQuery,axios 更加轻量化,只专注与网络数据请求

# axios 发起 GET 请求:

var url=''
var paramsObj={name:'zs',age:20}
axios.get(url,{params:paramsObj})
	.then(function(res){
		console.log(res)
		//res.data 服务器响应的数据
		console.log(res.data)
	})

# axios 发起 POST 请求:

var url='http://'
var dataObj={location:'Beijing',address:'haidian'}
axios.post(url,dataObj)
	.then(function(res){
		console.log(res)
		//res.data 服务器响应的数据
		console.log(res.data)
	})

# 直接使用 axios 发起请求:

axios 页提供了类似于 jQuery 中的 $.ajax () 的函数,语法如下:

axios({
	method:'GET'
	url:''
	//GET 参数要通过 params 属性提供
	params:{name:'zs',age:20}
})
	.then(function(res){
		console.log(res.data)
	})
-------------------------------------
axios({
	method:'POST'
	url:''
	//POST 参数要通过 data 属性提供
	data:{bookname:'thinking java',price:20}
})
	.then(function(res){
		console.log(res.data)
	})

#

# navigator.sendBeacon

// 性能中继器,使用不同指标来衡量和分析应用程序的性能
// 当页面上任何指标值完成计算时,将传递计算出的结果并触发这个函数
// 可以使用它将结果记录到控制台或者发送到特定端点
function sendTo(metric){
    const content = JSON.stringify(metric);
    if(navigator.sendBeacon){
        navigator.sendBeacon('http://test',content); //navigator.sendBeacon 的作用是
    }else{
        fetch('http://test.com',{
        content,
        method:'POST',
        keepAlive:true //fetch 中的 keepAlice 保证了即使页面刷新或者关闭,发出的请求仍然存在并进行,而不是进行到一半的请求突然停止
    }).then(()=>{
    console.log('发送成功');
    }).catch((e)=>{
        console.error(e);
    })
    }
}
reportWebVitals(sendTo); // 每一次得到计算结果都会执行一次

# 对比 Ajax fetch

# 优点
  1. 不受页面卸载过程的影响,确保数据可靠发送
  2. 异步执行,不阻塞页面关闭或跳转
  3. 能够发送跨域请求
# 缺点
  1. fetch 和 ajax 都可以发送任意请求 而 sendBeacon 只能发送 POST
  2. fetch 和 ajax 可以传输任意字节数据 而 sendBeacon 只能传送少量数据(64KB 以内)
  3. fetch 和 ajax 可以定义任意请求头 而 sendBeacon 无法自定义请求头
  4. sendBeacon 只能传输 ArrayBuffer ArrayBufferView Blob DOMString FormData URLSearchParams 类型的数据
  5. 如果处于危险的网络环境,或者开启了广告屏蔽插件 此请求将无效

# 应用场景

  1. 发送心跳包:可以使用 navigator.sendBeacon 发送心跳包,以保持与服务器的长连接,避免因为长时间没有网络请求而导致连接被关闭。
  2. 埋点:可以使用 navigator.sendBeacon 在页面关闭或卸载时记录用户在线时间,pv uv,以及错误日志上报 按钮点击次数。
  3. 发送用户反馈:可以使用 navigator.sendBeacon 发送用户反馈信息,如用户意见、bug 报告等,以便进行产品优化和改进
更新于 阅读次数

请我喝[茶]~( ̄▽ ̄)~*

dmq 微信支付

微信支付

dmq 支付宝

支付宝