Nodejs 第三十一章 响应头和请求头
在Node.js中,特别是在处理HTTP交互时,响应头(Response Headers)
和请求头(Request Headers)
扮演着非常关键的角色。理解它们的作用、必要性和解决的问题对于开发高效且安全的网络应用至关重要。
什么是响应头和请求头
请求头(Request Headers)
请求头是HTTP请求的一部分,包含了对服务器有用的信息,例如客户端想要进行的操作或者客户端的环境信息。它们帮助服务器了解如何处理接收到的请求。常见的请求头包括:
- Host:指定服务器的域名。
- User-Agent:标识发出请求的客户端类型,比如浏览器类型和版本。
- Accept :客户端能够接收的内容类型,如
text/html
或application/json
。 - Authorization:包含认证信息,用于访问需要验证的资源。
- Content-Type :请求体的媒体类型(如
application/json
),在POST和PUT请求中常见(我们在前面模拟发送POST请求的时候就经常用到这个)。
响应头(Response Headers)
响应头是服务器响应的一部分,向客户端回报关于响应的信息,如内容类型和状态信息。它们帮助客户端理解服务器返回的数据及如何处理这些数据。常见的响应头包括:
- Content-Type:响应体的内容类型,告诉客户端实际返回的数据类型。
- Content-Length:响应体的长度。
- Set-Cookie:向客户端发送的Cookie。
- Cache-Control:缓存策略,指示客户端如何缓存接收到的内容。
- Status:HTTP状态码,如200(成功)、404(未找到)或500(服务器错误)。
请求、响应头示例
- 存粹的知识点是无法记牢的,我们除了学习知识,还必须要知道这些能够运用在哪里?体现在哪里?这样的学习才是有意义的
- 通过打开网页的
控制台网络部分
,我们能够看到接口的标头部分就很明显的展示了响应头和请求头的具体参数,也许我们现在还看不懂他们。但这正是我们学习的意义,将未知转化为已知,下次就不会害怕打开这个部分看不懂 - 在这里我们可以看到请求头的内容很少,还有点小黄色警告,这是怎么回事?我们打开谷歌的技术文档就能找到原因了:原来是这请求接口是本地缓存提供的,而不是网络发送。而浏览器的缓存方式,我们在前面章节也有使用到,原来如此
- 文档链接:网络功能参考 | DevTools | Chrome for Developers
为什么需要它们?
请求头和响应头是HTTP协议的一部分,它们的设计初衷是为了使HTTP请求和响应更加灵活、高效。它们的存在有多个原因和优势:
- 通信控制:通过这些头信息,服务器可以了解请求的上下文,并据此作出适当的响应。同样,响应头可以控制客户端如何处理接收到的数据。
- 权限与认证:请求头可以包含认证信息,使得请求得以访问受保护的资源。
- 性能优化:响应头可以包含缓存指令,帮助减轻服务器负载,提高应用性能。
- 会话管理:通过Cookies和相关的头信息,可以管理用户的会话状态。
响应头和跨域之间的关系
曾经的我在学习ajax的时候,看的视频连什么是跨域都讲不清楚,导致我一直盲人摸象,学得很痛苦,也没学明白。所以在我们正是开始学习之前,我们一定要对跨域有一个整体的了解,这对我们的进度和顺利程度至关重要。
什么是跨域?
- 跨域是指在Web开发中,从一个源(origin)的页面去请求另一个源的资源。源由三个部分组成:协议(http、https)、主机(IP或域名)、端口号(如80, 443,3000等等)。只要这三者中有一个不同,就构成了跨域
- 它涉及到Web应用从一个域名(源)访问另一个域名的资源的权限问题
为什么会有跨域?
跨域的存在主要是由于浏览器的同源策略(Same-Origin Policy)引起的。同源策略是一个安全策略,它限制了一个源的文档或脚本如何与另一个源的资源进行交互。这个策略帮助防止恶意文档,减少可能的攻击,例如数据盗窃、恶意脚本执行等
。
跨域问题的表现
- API请求:最常见的情况是在使用AJAX(Asynchronous JavaScript and XML)或其他Web技术(如Fetch API)向不同源的服务器发起请求时遇到跨域错误。
- Web字体 (如由CDN托管的字体)、iframe 、图像 、样式表等的跨域使用,也可能受到同源策略的限制。
CORS
-
理解了跨域存在的必要性是很重要的,因为编程领域中,一定是不会在关键地方无缘无故给我们添堵的,能够一直存在下去,必然有着某种
衡量因素
在。- 就像朱元璋取缔了持续千年的丞相制度,但他没有意识到丞相制度能够坚持这么久必然有其原因,上千年下来有多少皇帝,其中不乏能力和朱元璋持平的皇帝,没有取消该制度,自然有对其的顾虑所在。朱元璋的行为在之后也导致了内阁大学士的出现,是另一种丞相制度的体现,并且相对于丞相制度而言,权力反而更加只手遮天
-
让我们把话题转回来,那什么是CORS呢?CORS就是跨域的一种常见解决方式
- 跨域资源共享(Cross-Origin Resource Sharing,CORS)是一种机制,用于在浏览器中实现跨域请求访问资源的权限控制。当一个网页通过 XMLHttpRequest 或 Fetch API 发起跨域请求时,浏览器会根据同源策略(Same-Origin Policy) 进行限制。
同源策略要求请求的源(协议、域名和端口)必须与资源的源相同,否则请求会被浏览器拒绝
- 跨域资源共享(Cross-Origin Resource Sharing,CORS)是一种机制,用于在浏览器中实现跨域请求访问资源的权限控制。当一个网页通过 XMLHttpRequest 或 Fetch API 发起跨域请求时,浏览器会根据同源策略(Same-Origin Policy) 进行限制。
nodemon第三方库
Nodemon 是一个流行的第三方库,用于开发基于 Node.js 的应用。它的主要功能是实时监视我们 Node.js 应用中的文件变动,并在检测到文件修改时自动重启服务器。是实现快速反馈循环的有力工具
主要功能
- 自动重启:Nodemon 会监控所有文件的变化,当保存了代码更改后,它会自动重启应用,省去了手动停止并重新启动服务器的麻烦。
- 配置灵活 :可以通过配置文件
nodemon.json
或命令行参数自定义监控的文件类型、忽略的文件和目录、延迟重启的时间等。
使用
-
首先安装一下:
npm install nodemon
-
在项目的
package.json
文件中添加一个使用 Nodemon 的启动脚本:
json
{
"scripts": {
"dev": "nodemon index.js"
}
}
配置示例
创建一个nodemon.json
文件在项目的根目录中,可以定义多种配置选项:
ignore
:设置忽略的文件或目录,不触发重启。watch
:设置需要监控的目录。delay
:设置重启延迟时间(毫秒)。ext
:设置需要监控的文件扩展名。
json
{
"ignore": ["*.test.js", "fixtures/*"],
"watch": ["src/"],
"delay": "1000",
"ext": "js,json"
}
初始化项目
- 创建index.html文件:在这个网页用来发送请求
- 创建index.js文件:在这个文件中编写接口请求
- 安装nodemon和express:实时监控和接口框架
- 最后在
package.json中
设置启动命令,让我们能npm run dev
直接启动写在index.js的服务端口。以及type
为module
,方便使用ESM导入
javascript
//index.html中模拟发送请求代码
fetch('http://localhost:3000/info').then(res=>{
return res.json()//将数据以JSON格式进行读取
}).then(res=>{
console.log(res)//然后才是真正获取处理好的数据
})
javascript
//index.js初始化服务代码
import express from "express"
const app = express()
app.get('/info', (req, res) => {
res.json({
code: 200,
type:'get'
})
})
app.listen(3000, () => {
console.log("3000端口开启成功");
})
端口不一致导致跨域
-
让我们来看看效果如何?
- 很显然,通过端口不一致的测试,也是成功在控制台报错了同源问题
csharp
Access to fetch at 'http://localhost:3000/info' from origin 'http://127.0.0.1:5500' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. If an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.
-
让我们来翻译下这段话吧!
- CORS 策略已阻止从原点 "http://127.0.0.1:5500 "访问 "http://localhost:3000/info": 请求的资源上没有 "Access-Control-Allow-Origin "标头。如果不透明响应符合您的需要,请将请求模式设置为 "no-cors",以便在禁用 CORS 的情况下获取资源。
- 这就是跨域错误,而且和我们的CORS好像扯上了关系。目前来看,我们不仅端口不一,连IP也不一,但其实我们直接把127.0.0.1改成localhost就OK了。返回的报错也是一样的
- 请注意报错,他说我们请求的资源上没有
Access-Control-Allow-Origin
标头,那我们就应该让我们请求的资源上有,至于怎么做?我们往下看
-
此时我们做到了IP是一样的了,但端口除非是前后端不分离的项目才可以做一样,但现在的项目都是以前后端分离为主(人不分离)
-
此时就需要后端设置一个响应头(标头),允许前端去访问该资源
-
我们在Node中设置一个相关的中间件来解决:
- 这里需要注意,我们设置响应头的时候,是支持后端的session的,但只有指定IP或者网址才行,
*
是获取不到的 Session
是一种服务器端存储机制,用于存储特定用户的信息状态和跨多个页面访问或多个请求之间的状态信息。它主要用于识别用户和保持用户状态。当用户浏览一个网站时,session 可以帮助维持用户登录状态和跟踪用户的行为。
- 这里需要注意,我们设置响应头的时候,是支持后端的session的,但只有指定IP或者网址才行,
javascript
//记得写在请求的前面
app.use('*',(req,res,next)=>{
//这里我们设置的是Origin(固定的某个源,也就是IP或网址),但其实还可以设置为*(相当于全部放开,所有人都可以访问,有点危险哦)
res.setHeader('Access-Control-Allow-Origin','http://localhost:5500')//允许localhost 5500 访问
next()
})
- 现在我们再看控制台,就已经正确返回内容了。通过后端的放行(请求的资源上已经有我们的标头了),我们成功跨过了同源策略的限制
- 就算通过网络工具观察info这条接口信息,也能看到
Access-Control-Allow-Origin
返回的是固定的源(我们刚才设置的)了。而刚才在没有设置的时候,这里是空空如也的状态
额外的请求方式
- 虽然我们平时一般也就使用GET和POST请求,但如果我们要遵循
restFui
风格,比如PATCH
或者其他请求的时候
javascript
//服务端接口请求
app.patch('/info', (req, res) => {
res.json({
code: 200,
type:'get'
})
})
javascript
//index.html文件
fetch('http://localhost:3000/info', {
method: 'PATCH'//默认是GET请求,我们将其改为PATCH
}).then(res => {
return res.json()
}).then(res => {
console.log(res)
})
- Access to fetch at 'http://localhost:3000/info' from origin 'http://localhost:5500' has been blocked by CORS policy: Method PATCH is not allowed by Access-Control-Allow-Methods in preflight response.
- 那怎么又完蛋了,说我们PATCH不被
Access-Control-Allow-Methods
包括,这就跟我们要说到的第二个响应头有关系了
arduino
res.setHeader('Access-Control-Allow-Methods', 'PATCH')
- 我们响应头默认情况下只支持GET,POST,HEAD,OPTIONS等方式。而PATCH显然不再这个范围内,想要服务器支持
PUT
,DELETE
, 等其他HTTP方法的跨源请求,则需要在响应头中明确指出
预检请求 OPTIONS
在HTTP协议中,OPTIONS
请求方法是一种预检请求,用来在实际发送另一个请求之前,检测服务器对特定请求的支持情况。这主要用于网络中的跨源资源共享(CORS)场景。
-
OPTIONS请求是浏览器发起的,满足以下任意一点即会发起:
- 自定义请求方法:当使用非简单请求方法(Simple Request Methods)时,例如 PUT、DELETE、CONNECT、OPTIONS、TRACE、PATCH 等,浏览器会发送预检请求。
- 自定义请求头部字段 :当请求包含自定义的头部字段时,浏览器会发送预检请求。
自定义头部字段是指不属于简单请求头部字段列表的字段
,例如 Content-Type 为 application/json、Authorization 等。 - 带凭证的请求:当请求需要在跨域环境下发送和接收凭证(例如包含 cookies、HTTP 认证等凭证信息)时,浏览器会发送预检请求。
主要功能
OPTIONS
请求的主要功能是询问服务器,针对某个跨域资源,服务器支持哪些HTTP方法和头部信息。这是特别重要的,因为它帮助客户端确定是否可以安全地发起一个跨源请求。
工作原理
当我们尝试从一个源(如域名A)发起对另一个源(如域名B)的请求时,浏览器会首先使用OPTIONS
请求方法发送一个预检请求到服务器。这个请求会包括以下几个重要的HTTP头部信息:
Access-Control-Request-Method
: 这个头部信息告诉服务器,实际的请求将使用哪个HTTP方法(如POST或PUT)。Access-Control-Request-Headers
: 如果实际请求中将包含自定义头部信息,这个头部会列出那些头部。
服务器响应
对于这个OPTIONS
请求,服务器需要响应以下信息:
Access-Control-Allow-Origin
: 指明哪些域名可以访问资源。Access-Control-Allow-Methods
: 指明哪些HTTP方法被允许。Access-Control-Allow-Headers
: 指明在实际请求中可以使用哪些HTTP头部。Access-Control-Max-Age
: 指明浏览器应该将预检请求的结果缓存多长时间。
代码测试
- 我们设置好了响应头的
headers
的内容类型,然后看下控制台的情况
javascript
fetch('http://localhost:3000/info',{
method:'POST',
headers:{
'Content-Type':'application/json'
},
body:JSON.stringify({name:'xioayu'})
}).then(res=>{
return res.json()
}).then(res=>{
console.log(res)
})
- 此时的错误并不是跨域错误了,这是一个CORS的错误
Access to fetch at 'http://localhost:3000/info' from origin 'http://localhost:5500' has been blocked by CORS policy: Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response
-
我们敏锐的察觉到了关键词:
Access-Control-Allow-Headers
,好像又是一个新的词汇,这是什么意思?Access-Control-Allow-Headers
: 指明在实际请求中可以使用哪些HTTP头部。然后我们应该是不达标,这里的HTTP头部其实就是响应头 或者标头。- 我们实际的原因则是因为
application/json
不属于cors 范畴,需要手动支持。 - 说得更明白点的话,则是
Content-Type
默认情况下只支持以下三个:
Content-Type 用途 描述 application/x-www-form-urlencoded
通常用于HTML表单提交 数据被编码为键值对,类似于URI查询字符串。键和值之间用 =
连接,对之间用&
分隔。multipart/form-data
用于HTML表单文件上传以及发送非ASCII数据或大量数据 允许多部分数据进行发送,每个部分都可以有自己的 Content-Type
,适用于文件或其他数据。text/plain
简单文本数据的提交 数据以纯文本形式发送,没有特定格式。常用于发送文本数据。
- 而我们的
application/json
不在其中,所以说报了这个错误。本质上来说,这个问题跟前面报请求方法不在范围是一样的。只是这次不在的是Headers,而不是Methods而已 - 那怎么做?往响应头上加不就OK了,让我们来看下怎么写吧
arduino
res.setHeader('Access-Control-Allow-Headers', 'Content-Type')
-
和之前还是一样的,不过我们这次要添加的是
Content-Type
,因为application/json
就是Content-Type
的一个选项- 此时我们在看控制台,内容就如期打印了
- 通过打开接口,跨域看到我们已经设置的三个标头参数,也包括了
Headers
使用场景
- 跨域请求 :在跨域请求中,
OPTIONS
请求用于确认服务器是否允许来自不同源的特定类型的HTTP请求。 - RESTful APIs :在REST架构中,
OPTIONS
请求方法可以用来获取关于服务器端某个资源的元信息,如服务器支持的方法列表等。
自定义响应头
什么是自定义响应头?
自定义响应头是在HTTP响应中由服务器设置的、不属于标准HTTP响应头的额外头部信息。这些响应头主要用于传递
非标准化的、特定于应用的数据
,或者用于控制如何处理或解释服务器响应的某些方面。自定义响应头可以提供有关服务器或响应的额外信息,增强客户端与服务器间的通信,或支持特定的功能和服务。
- 这么长的一段话,其实最重要的就是那个
"非标准化"
,我们可以理解为独门定制。专门为特定的情况去专门设立的,肯定是更加贴合,而这就是它出现的意义。使用的自由度更上一层
案例
- 让我们把前面设置的响应头内容暂且注释掉,然后来使用下自定义的响应头试一试。我们就把这个响应头命名为Xiao-Yu吧!
javascript
//写在设置响应头的中间件中
app.use('*', (req, res, next) => {
//这里我们设置的是Origin(固定的某个源),但其实还可以设置为*(相当于全部放开,所有人都可以访问,有点危险哦)
res.setHeader('Access-Control-Allow-Origin', 'http://127.0.0.1:5500')//允许localhost 5500 访问
// res.setHeader('Access-Control-Allow-Methods', 'POST,GET,OPTIONS,DELETE,PATCH')
// res.setHeader('Access-Control-Allow-Headers', 'Content-Type')
res.set('Xiao-Yu', '666')
next()
})
javascript
fetch('http://localhost:3000/info').then(res => res.json()).then(res => {
console.log(res)
})
- 能够看到,响应标头(响应头)中,明显的出现了我们自定义的内容
获取自定义内容
-
我们既然能够设置自定义的内容,那肯定是需要能够读取到的,不然能看不能拿就没有意义了。那我们要怎么才能拿到这里的内容呢?
- 如果我们能够取到
Xiaoyu
这个自定义的内容,就基本上说明其他的标准内容,就更容易取到了
- 如果我们能够取到
-
我们先来看看标准的内容怎么获取
javascript
fetch('http://localhost:3000/info').then(res => {
const Header = res.headers
return Header.get('Content-Type')
}).then(res => {
console.log(res)
})
-
很简单的就拿到了,那我们就一鼓作气的拿到我们自定义的内容吧!
- 可惜并没有这么简单,如果我们就这样直接去拿的话,就只会是null,不仅仅自定义内容是这样,就连我们设置的
Access-Control-Allow-Origin
也拿不到。这又是为什么? - 这就需要涉及到我们又一个知识点了,因为后端没有抛出该响应头所以后端需要增加抛出的一个字段。而这个字段就是
Access-Control-Expose-Headers
,一看就知道跟我们之前使用的是一个系列的了,学到这里,我们已经用到好多个了,等下我会将其整理成表格统一对比
- 可惜并没有这么简单,如果我们就这样直接去拿的话,就只会是null,不仅仅自定义内容是这样,就连我们设置的
c
res.set('Xiao-Yu', '666')
res.setHeader('Access-Control-Expose-Headers', 'Xiao-Yu')
- 我们设置了内容,想要前端能够获取到,则后端就必须要将其抛出去。现在我们再来用响应头中header的
get方法
获取一下吧
javascript
fetch('http://localhost:3000/info').then(res => {
const Header = res.headers
return Header.get('Xiao-Yu')
}).then(res => {
console.log(res)
})
- 此时就能够正常的获得了
SSE单工通讯
什么SSE
SSE(Server-Sent Events)单工通讯是一种允许服务器主动向客户端发送信息更新的技术。与传统的请求/响应模式不同,SSE提供了一种建立持久连接的方法,通过这种连接,服务器可以实时地发送新数据到客户端,而无需客户端不断地发起请求。
解决的问题
- 减少请求开销:在传统的HTTP轮询中,客户端需要定期发送请求到服务器以检查是否有数据更新。这种方式会产生大量冗余的请求和数据流量,因为即使没有数据更新,连接也需要被频繁地建立和关闭。SSE通过保持单个持久连接来解决这个问题,服务器只在真正有数据更新时才发送信息。
- 实时性:对于需要实时或近实时数据的应用(如新闻推送、股票价格更新、社交媒体实时通知等),SSE提供了比轮询更有效、更及时的解决方案。
- 简化客户端逻辑:客户端不需要不断地检查更新,只需监听服务器发送的事件即可,这简化了客户端逻辑并提高了应用的性能。
应用意义
- 提高用户体验:用户可以得到即时的更新,不再需要手动刷新页面或等待下一个轮询周期,从而大大提升了用户体验。
- 优化资源使用:减少了不必要的数据传输和服务器资源消耗,因为只有在真正有数据更新时才会进行数据传输。
- 易于实现和兼容:SSE是基于标准HTTP协议实现的,开发者可以使用简单的HTTP响应来实现,不需要特殊的协议支持,且客户端实现较为简单,主要是浏览器已经内置了对SSE的支持。
其实听起来,像是webSocket的弱化版本(这个就能做聊天室了)
webSocket
属于全双工通讯,也就是前后端可以互相实时发送信息,SSE属于单工通讯,后端可以给前端实时发送。- 因为我们有时候完全用不上
webSocket
的完整功能,只需要它的部分能力,而SSE就是为此诞生的。- 比如大屏的项目,需要实时展示后端传递过来的信息数据,在页面上及时反馈。但我们知道大屏项目这种东西,其实就是用来看的,而不可能像微信说还要往里面输入内容,那不至于。那此时用
webSocket
就浪费了,而用SSE单工通讯
则刚刚好
代码实现
- 在使用 Express.js 创建 Server-Sent Events (SSE) 应用时,设置响应头
Content-Type
为text/event-stream
是实现单工通讯的关键步骤。这种设置使得服务器可以持续地向客户端发送数据,而客户端无需再次请求即可接收到更新。这就是所谓的单工通讯,即数据只从服务器单向流向客户端,而不需要客户端向服务器回送数据。
详细理解
-
设置响应头 :在 Express 中,当设置响应头
Content-Type
为text/event-stream
时,这告诉浏览器接下来的响应是一个持续的流,不是一次性响应。浏览器将保持请求打开,并准备从服务器接收更多数据。 -
单工通讯:在单工通讯模型中,服务器不断推送信息给客户端,而客户端只是接收。这与双向通讯(如 WebSocket)不同,双向通讯中客户端和服务器都可以发送和接收信息。
-
事件和数据:在 SSE 中,服务器可以发送不同类型的事件和数据给客户端。服务器通过特定的格式发送消息:
- 事件类型 :通过
event: someEventName
指定,客户端可以根据事件类型决定如何处理接收到的数据。 - 数据 :通过
data: someData
发送,可以是简单的字符串或经过 JSON 编码的复杂对象。
- 事件类型 :通过
javascript
app.get('/sse',(req,res)=>{
res.setHeader('Content-Type', 'text/event-stream')
res.status(200)
//使用定时器测试,看是不是1秒返回一次当前最新时间
setInterval(() => {
res.write('event: test\n')
res.write('data: ' + new Date().getTime() + '\n\n')
}, 1000)
})
-
这里需要注意在使用 Server-Sent Events (SSE) 来发送事件流时,要遵循一定的格式来确保事件能被客户端的
EventSource
正确解析。在我们的示例中,通过res.write()
发送的信息包括两个部分:事件类型和数据内容。这一点很重要,是运行的规律-
事件类型 (
event
):event: test\n
- 这一行定义了事件的名称为 "test"。在客户端的
EventSource
中,可以使用addEventListener
监听这个具体的事件名。 - 在没有指定
event
的情况下,事件默认被视为 "message",可以通过onmessage
处理器接收。
-
数据内容 (
data
):data: ' + new Date().getTime() + '\n\n'
- 这一行发送的是实际的事件数据。在这个例子中,数据是当前的时间戳。
- 数据行以
data:
开头,后面跟着具体的数据内容。 - 数据可以跨多行发送,每行都必须以
data:
开始。 - 事件数据的结束由一个空行标识,即连续的两个换行符
\n\n
。这个空行是必须的,它告诉客户端数据发送完毕。
-
前端接收内容
-
把后端实时发送过来的内容进行一个实时的接收打印在控制台
- 此时前端就无法用接口接住这次的数据了,而是采用
EventSource
接收,Source(来源) - 在构建基于 Server-Sent Events (SSE) 的实时数据流应用时,前端通常会使用
EventSource
接口。这是一个由浏览器提供的 Web API,专门用来处理从服务器接收的事件流。EventSource
的使用主要是为了方便地建立一个到服务器的持久连接,并接收通过text/event-stream
响应头发送的事件。
- 此时前端就无法用接口接住这次的数据了,而是采用
javascript
const sse = new EventSource('http://localhost:3000/sse')
//是可以通过多个事件监听的
sse.addEventListener('message', (ev) => {
console.log(ev);
})
sse.addEventListener('test', (event) => {
console.log(event.data)
})
- 控制台输出也是可以的,这里直接输出的是毫秒,我们需要自己实时转化一下的
为什么需要 EventSource
- 简化客户端逻辑 :
EventSource
API 抽象了许多底层的网络操作,使得开发者可以轻松实现对服务器发送的事件的监听和处理,而无需手动管理 HTTP 连接或解析事件数据。 - 自动重连 :一个重要的特性是,当连接因网络问题或服务器重启而断开时,
EventSource
会自动尝试重新连接。这意味着开发者不需要编写额外的逻辑来处理连接重试。 - 标准化的事件处理 :使用
EventSource
,服务器可以发送具名事件,客户端可以根据事件名注册处理函数,这使得事件处理更为直观和组织化。
总结
- 这一期的内容非常多,也用到了很多类似的响应头内容,为了防止我们记岔了,在这里要进行总结一下我们该文章用到的部分(按顺序)
响应头 | 作用 |
---|---|
Access-Control-Allow-Origin |
指定哪些域可以访问资源。例如 * 表示任何域都可以访问,或者指定如 https://juejin.com 只允许特定域访问。 |
Access-Control-Allow-Methods |
列出允许的HTTP请求方法(如 GET , POST , DELETE 等)。用于在预检请求中告诉客户端服务器允许的方法,以便后续的实际请求中使用。 |
Access-Control-Allow-Headers |
指定实际请求中允许携带的HTTP头列表。例如 Content-Type , Authorization 等。 |
Access-Control-Expose-Headers |
允许客户端能够访问的服务端的响应头列表。通常情况下,客户端无法获取除基本头之外的响应头,除非这里明确允许。通过这个可以抛出自定义响应头 |