Fetch API

Fetch API

Fetch API 提供了一个 JavaScript 接口,用于访问和操纵 HTTP 管道的一些具体部分,例如请求和响应。它还提供了一个全局 fetch() 方法,该方法提供了一种简单,合理的方式来跨网络异步获取资源。

fetch()

用于发起获取资源的请求。它返回一个 promise,这个 promise 会在请求响应后被 resolve,并传回 Response 对象。

1
fetch(url[, init])	//init:对请求的设置

同步方式接收响应

1
const 结果 = await Promise	//会阻塞之后的代码,直到接收到响应结果
  • await 关键字必须在一个标记了 async 的 function 内来使用

案例

前面的部分

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<div>
<div class="title">学生列表</div>
<div class="thead">
<div class="row bold">
<div class="col">编号</div>
<div class="col">姓名</div>
<div class="col">性别</div>
<div class="col">年龄</div>
</div>
</div>
<div class="tbody">
</div>
</div>

<template id="tp">
<div class="row">
<div class="col">xx</div>
<div class="col">xx</div>
<div class="col">xx</div>
<div class="col">xx</div>
</div>
</template>

同步接收数据,并写到html表单里

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<script>
async function findStudents() {
// 向students.json发送request请求
const resp = await fetch('students.json')
// 获取响应体,按json方式解析
const array = await resp.json(); //.json返回的还是一个Promise

// 获取模板
const tp = document.getElementById("tp");
const row = tp.content;

// 将数据填入模板,并复制到要显示的文本中
const [c1, c2, c3, c4] = row.querySelectorAll(".col");
const tbody = document.querySelector('.tbody');
for (const {id, name, sex, age} of array) {
c1.textContent = id;
c2.textContent = name;
c3.textContent = sex;
c4.textContent = age;

const newRow = document.importNode(row, true);
tbody.appendChild(newRow);
}
}
findStudents();
</script>

异步方式接收响应

通过.then来异步接收响应

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<script>
fetch('students.json')
.then(resp => resp.json())
.then(array => {
// 获取模板
const tp = document.getElementById("tp");
const row = tp.content;

// 将数据填入模板,并复制到要显示的文本中
const [c1, c2, c3, c4] = row.querySelectorAll(".col");
const tbody = document.querySelector('.tbody');
for (const {id, name, sex, age} of array) {
c1.textContent = id;
c2.textContent = name;
c3.textContent = sex;
c4.textContent = age;

const newRow = document.importNode(row, true);
tbody.appendChild(newRow);
}
})
.catch(e => console.log(e)) //捕获异常
</script>

跨域问题

同源检查是浏览器的行为,而且只针对 fetch、xhr(XMLHTTPRequest) 请求

只要协议、主机、端口之一不同,就不同源

  • fetch 请求跨域,会携带一个 Origin 头,代表【发请求的资源源自何处】,目标通过它就能辨别是否发生跨域
  • 目标资源通过返回 Access-Control-Allow-Origin 头,告诉浏览器【允许哪些源使用此响应】

通过添加响应头解决

  • java后端添加注解CrossOrigin来添加 Access-Control-Allow-Origin响应头

    1
    2
    3
    4
    5
    @GetMapping("/api/students")
    @CrossOrigin("http://localhost:7070")
    public R all() {
    return R.ok(studentService.findAll());
    }
  • 也可以通过配置类配置全局跨域

    实现WebMvcConfigurer的addCorsMappings方法

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    @Configuration
    public class WebConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
    registry.addMapping("/**")
    // 设置允许跨域请求的域名
    .allowedOriginPatterns("http://localhost:8080")
    // 是否允许携带cookie
    .allowCredentials(true)
    // 设置允许的请求方式
    .allowedMethods("GET", "POST", "DELETE", "PUT")
    // 设置允许的header属性
    .allowedHeaders("*")
    // 跨域允许的时间
    .maxAge(3600);
    }
    }

通过代理解决

浏览器要访问跨域的资源时,将请求发到前端的代理中,让代理去获得资源再返回

  • 安装

    1
    npm install http-proxy-middleware --save-dev
  • 在启动代码中导入

    1
    2
    3
    4
    import {createProxyMiddleware} from 'http-proxy-middleware'

    //创建代理中间件,请求url为'/api'的都会被代理
    app.use('/api', createProxyMiddleware({ target: 'http://localhost:8080', changeOrigin: true }));

Fetch API
http://xwww12.github.io/2022/10/04/前端/api/FetchAPI/
作者
xw
发布于
2022年10月4日
许可协议