当前位置: 首页 > news >正文

WEB前端10- Fetch API(同步/异步/跨域处理)

Fetch API

Fetch API 可以用来获取远程数据,用于在 Web 应用程序中发起和处理 HTTP 请求。它基于 Promise,提供了一种简单而强大的方式来处理网络通信,替代了传统的 XMLHttpRequest。

  • Promise对象

Promise 对象是 JavaScript 中处理异步操作的一种机制,它代表了一个异步操作的最终完成或失败,并且其结果值是可用的。

基本概念

  1. 状态(State)
    • Promise 可以处于三种状态之一:pending(进行中)、fulfilled(已成功)或 rejected(已失败)。
    • 当创建一个 Promise 对象时,它最初是 pending 状态,随后可能变为 fulfilled 或 rejected。
  2. 值(Value)
    • 当 Promise 从 pending 变为 fulfilled 时,会传递一个值作为操作成功的结果。
    • 当 Promise 从 pending 变为 rejected 时,会传递一个原因(通常是 Error 对象)作为操作失败的原因。
  3. 处理异步操作
    • Promise 对象用于处理异步操作,可以通过 .then() 方法注册成功和失败的回调函数,或者使用 .catch() 方法捕获失败的情况。
  • Fetch发起网络请求
fetch(url, options);//返回

url: 表示要获取资源的 URL 的字符串。

options: (可选)一个对象,包含配置 fetch 操作的设置,比如方法、头部、请求体、凭据等。这个参数允许精确调整请求的细节。

返回值:fetch(url, options) 函数返回一个 Promise 对象,它代表了请求的异步操作。这个 Promise 对象在请求完成后会resolve(解析),返回一个 Response 对象,或在出现网络错误时reject(拒绝),返回一个错误。

具体来说:

如果请求成功并且得到了 HTTP 状态码在 200299 之间的响应(包括 200299),`fetch()` Promise 的状态将会是 resolved,而且 `Response` 对象将作为 resolve 的值传递。如果出现网络错误,比如无法连接服务器或者请求超时,`fetch()` Promise 的状态将会是 rejected,并且会传递一个错误对象给 `.catch()` 方法处理。
  • 接受数据的方式

**同步方式:**后续代码不会在结果返回前执行

const response = await fetch(url, options);//获得响应对象

注意:await 关键字必须在一个标记了 async 的 function 内来使用

**异步方式:**后续代码不必等待结果返回就可以执行

fetch(url, options).then(结果 => { ... })
.then 方法:
.then() 是 Promise 对象的方法,接收一个回调函数作为参数。这个回调函数会在 Promise 对象的状态变为 resolved 时被调用。
回调函数中的 结果 参数是 Promise 对象成功解析后传递给 .then() 方法的值。结果 => { ... }:
这是一个箭头函数,或者称为回调函数,它接收一个参数 结果,这个参数是 Promise 解析后的值。
大括号 { ... } 中包含了具体要执行的操作或逻辑。
  • 跨域问题

image-20220814105448882

跨域原因:

跨域问题的出现主要是由于浏览器的同源策略(Same-Origin Policy)限制所导致的。同源策略是一种安全机制,旨在防止一个网页上的脚本获取另一个网页的数据。具体来说,同源策略要求网页中的所有资源(如脚本、样式表和 AJAX 请求)必须来自同一个域、协议和端口,否则就会出现跨域问题。

以下是导致跨域问题的主要原因:

  1. 不同域名: 当浏览器发起请求的源(Origin)与资源所在服务器的域名不一致时,就会发生跨域请求。例如,从 http://domain1.com 发起请求访问 http://domain2.com 上的资源。
  2. 不同子域名: 即使是同一个顶级域名,不同子域名之间也被视为不同的源。例如,http://sub1.domain.comhttp://sub2.domain.com 之间的请求就属于跨域请求。
  3. 不同协议: 当浏览器中的页面由 http:// 协议访问,而请求的资源是通过 https:// 协议提供时,也会遇到跨域问题。
  4. 不同端口: 即使是同一域名下的不同端口,例如从 http://domain.com:3000 访问 http://domain.com:4000 的资源,也会被浏览器视为跨域请求。
  5. 安全策略限制: 除了同源策略,浏览器还会根据安全策略(如 Content Security Policy)对跨域请求进行限制和防范,这也可能导致跨域问题的出现。

解决方案:

1.响应头解决方案

跨域请求的主要机制之一是使用响应头来进行控制和验证。当浏览器发起跨域请求时,例如从 http://localhost:7070http://localhost:8080 发送请求,浏览器会在请求中携带一个 Origin 头,表明请求的源自何处。

服务器端可以通过设置 Access-Control-Allow-Origin 头来响应这个请求。例如,如果服务器允许来自 http://localhost:7070 的请求访问资源,可以设置响应头如下:

image-20220814144040703

response.addHeader("Access-Control-Allow-Origin", "http://localhost:7070");

这样浏览器就可以根据响应头确定是否允许将响应传递给请求的页面。

2.代理解决方案

另一个常见的跨域解决方案是使用代理。代理服务器充当客户端和目标服务器之间的中介,它接收来自客户端的请求,然后将请求转发给目标服务器,并将目标服务器的响应返回给客户端。

image-20220814161532141

在 Node.js 的 Express 框架中,可以使用 http-proxy-middleware 中间件来设置代理。下面是如何配置和使用该中间件的示例代码:

首先,安装 http-proxy-middleware

npm install http-proxy-middleware --save-dev

然后,在 Express 服务器的启动代码中加入如下配置:

import { createProxyMiddleware } from 'http-proxy-middleware';
const express = require('express');
const app = express();// 设置代理,将请求转发到目标服务器
app.use('/api', createProxyMiddleware({ target: 'http://localhost:8080', changeOrigin: true }));// 其他 Express 中间件和路由设置
// ...// 启动 Express 服务器
app.listen(7070, () => {console.log('Express server is running on http://localhost:7070');
});

这段代码将会把所有以 /api 开头的请求都代理到 http://localhost:8080,并且将 Origin 头设置为当前的源。

最后,需要确保在客户端的 Fetch 请求中正确使用代理路径。例如,将之前的 Fetch 请求:

const resp = await fetch('http://localhost:7070/api/students');

修改为使用代理路径:

const resp = await fetch('/api/students');

这样客户端代码就会自动将请求发送到 http://localhost:7070/api/students,并通过代理转发到目标服务器上。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • 基于Markdown的文档网站生成工具-VitePress框架
  • 强制通风(2):发动机为什么要进行曲轴强制通风?它的目的是什么呢?
  • 深入 Symfony 服务容器:依赖注入的艺术
  • 基于web的物流配送管理系统/基于客户时间窗变化的物流配送管理系统/快递配送管理系统
  • AI发展下的伦理挑战,应当如何应对?
  • go语言day15 goroutine
  • 搜索与下载Stable Diffusion 模型
  • ResT v2 论文解读
  • Python Formulas模型以JSON格式文件导出导入
  • 运行ruoyi
  • 秋招突击——7/23——百度提前批面试准备和正式面试
  • vivado IOSTANDARD
  • 计算机网络-配置双机三层互联(静态路由方式)
  • 独立游戏《星尘异变》UE5 C++程序开发日志8——实现敏感词过滤功能(AC自动机)
  • TCP服务器主动断开客户端
  • SegmentFault for Android 3.0 发布
  • 【css3】浏览器内核及其兼容性
  • ES2017异步函数现已正式可用
  • golang 发送GET和POST示例
  • HomeBrew常规使用教程
  • JSDuck 与 AngularJS 融合技巧
  • mysql外键的使用
  • Nodejs和JavaWeb协助开发
  • Redis的resp协议
  • SpringCloud集成分布式事务LCN (一)
  • Vultr 教程目录
  • yii2中session跨域名的问题
  • 一起参Ember.js讨论、问答社区。
  • ​【原创】基于SSM的酒店预约管理系统(酒店管理系统毕业设计)
  • ​linux启动进程的方式
  • # Panda3d 碰撞检测系统介绍
  • # windows 安装 mysql 显示 no packages found 解决方法
  • #调用传感器数据_Flink使用函数之监控传感器温度上升提醒
  • #图像处理
  • (ZT)北大教授朱青生给学生的一封信:大学,更是一个科学的保证
  • (汇总)os模块以及shutil模块对文件的操作
  • (排序详解之 堆排序)
  • (实测可用)(3)Git的使用——RT Thread Stdio添加的软件包,github与gitee冲突造成无法上传文件到gitee
  • (转)负载均衡,回话保持,cookie
  • .gitignore文件---让git自动忽略指定文件
  • .java 指数平滑_转载:二次指数平滑法求预测值的Java代码
  • .net websocket 获取http登录的用户_如何解密浏览器的登录密码?获取浏览器内用户信息?...
  • .net 后台导出excel ,word
  • .NET 简介:跨平台、开源、高性能的开发平台
  • .NET/C# 的字符串暂存池
  • .NET大文件上传知识整理
  • .net反混淆脱壳工具de4dot的使用
  • .NET开发者必备的11款免费工具
  • @select 怎么写存储过程_你知道select语句和update语句分别是怎么执行的吗?
  • @基于大模型的旅游路线推荐方案
  • [ Socket学习 ] 第一章:网络基础知识
  • [Android Pro] Notification的使用
  • [C++数据结构](31)哈夫曼树,哈夫曼编码与解码
  • [CodeForces-759D]Bacterial Melee
  • [C语言]一维数组二维数组的大小