手写场景 | 三种不同的网络请求方式实现列表动态渲染

前情提要

突()发()奇()想()想基于AJAX封装、axios、fetch实现同一种效果

我想实现的效果很简单:基于URL返回数据并且动态渲染在页面上

在此感谢,Github某老哥提供的接口:https://github.com/Binaryify/NeteaseCloudMusicApi

准备工作

  • BASE_URL:'http://localhost:3000'
  • 接口文档:'/artist/top/song?id=' + id ,示例为'/artist/top/song?id=6452'
  • data数据结构如下:
1
2
3
4
5
6
7
8
9
10
// mock
const data = [
{name: xxx, xxx: xxx, ...},
{name: xxx, xxx: xxx, ...},
{name: xxx, xxx: xxx, ...},
{name: xxx, xxx: xxx, ...},
{name: xxx, xxx: xxx, ...},
{name: xxx, xxx: xxx, ...},
...
]
  • 动态渲染函数
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function getList(data) {
for (let i = 0; i < data.length; i++) {
// 获取ul
const ul = document.getElementsByTagName('ul')[0];
// 动态渲染数据
data.forEach((item) => {
// 创建li节点
let li = document.createElement('li');
// 给li添加文本内容
li.innerHTML = item.name; // 我只想渲染name
// 把li添加到ul下作为子节点
ul.appendChild(li);
});
}
}

方式1:基于Promise封装的AJAX

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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>axios</title>
<link crossorigin="anonymous" href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<style>
</style>
<body>
<div class="container">
<h2 class="page-header">ajax</h2>
<button class="btn btn-primary">发送GET请求</button>
<h3 class="page-header">数据展示</h3>
<ul class = 'list'></ul>
</div>
<script>
// Promise封装AJAX
function myAJAX(method='GET', url='', isAysnc=true, data=null) {
// 新建xhr对象
let xhr = new XMLHttpRequest();

return new Promise((resolve, reject)=> {
// 监听状态变化
xhr.onreadystatechange = function() {
if (xhr.readyState !== 4) return;
if (xhr.readyState === 4) {
if (xhr.status >= 200 && xhr.status < 300 || xhr.status === 304) {
resolve(xhr.responseText);
} else {
reject(xhr.statusText);
}
}
};

// 建立连接
xhr.open(method, url, isAysnc);

// 发送请求
xhr.send(data);
});
}


// 动态渲染函数
function getList(data) {
// console.log('d', data);
// 获取ul
const ul = document.getElementsByTagName('ul')[0];
// 循环输出数据
data.forEach((item, index) => {
// 创建li
let li = document.createElement('li');
// 指定文本内容插入li中
li.innerHTML = item.name;
// 创建的li插入ul中
ul.appendChild(li);
})
}

const BASE_URL = 'http://localhost:3000';

// 需求1:获取热门50首歌曲 id为6452
const hotSongsRequest = (id) => myAJAX('GET', BASE_URL + '/artist/top/song?id=' + id, true, null);

const btns = document.getElementsByTagName('button');

btns[0].addEventListener('click', () => {
let res = hotSongsRequest(6452);
res.then(value => {
let data = JSON.parse(value);
getList(data.songs);
}, err => {
console.log(err);
})
})
</script>
</body>
</html>

方式2:axios

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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>ajax</title>
<link crossorigin="anonymous" href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
<script src="https://cdn.bootcdn.net/ajax/libs/axios/0.26.0/axios.min.js"></script>
</head>
<style>
</style>
<body>
<div class="container">
<h2 class="page-header">axios</h2>
<button class="btn btn-primary">发送GET请求</button>
<h3 class="page-header">数据展示</h3>
<ul class = 'list'></ul>
</div>
<script>
// 动态渲染函数
function getList(data) {
// console.log('d', data);
// 获取ul
const ul = document.getElementsByTagName('ul')[0];
// 循环输出数据
data.forEach((item, index) => {
// 创建li
let li = document.createElement('li');
// 指定文本内容插入li中
li.innerHTML = item.name;
// 创建的li插入ul中
ul.appendChild(li);
})
}

const BASE_URL = 'http://localhost:3000';


// 需求1:获取热门50首歌曲 id为6452
const hotSongsRequest = (id) => {
axios({
method: 'GET',
url: BASE_URL + '/artist/top/song?id=' + id,
}).then(value => {
let data = value.data;
getList(data.songs);
}).catch(err => {
console.log(err);
})
};

const btns = document.getElementsByTagName('button');

btns[0].addEventListener('click', () => hotSongsRequest(6452));
</script>
</body>
</html>

方式3:fetch

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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>fetch</title>
<link crossorigin="anonymous" href="https://cdn.bootcss.com/twitter-bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet">
</head>
<style>
</style>
<body>
<div class="container">
<h2 class="page-header">fetch</h2>
<button class="btn btn-primary">发送GET请求</button>
<h3 class="page-header">数据展示</h3>
<ul class = 'list'></ul>
</div>
<script>
// 动态渲染函数
function getList(data) {
// console.log('d', data);
// 获取ul
const ul = document.getElementsByTagName('ul')[0];
// 循环输出数据
data.forEach((item, index) => {
// 创建li
let li = document.createElement('li');
// 指定文本内容插入li中
li.innerHTML = item.name;
// 创建的li插入ul中
ul.appendChild(li);
})
}

const BASE_URL = 'http://localhost:3000';

// 需求1:获取热门50首歌曲 id为6452
const hotSongsRequest = (id) => {
const url = BASE_URL + '/artist/top/song?id=' + id;
fetch(url).then(response => {
response.json().then(value => {
let data = value.songs;
getList(data);
})
})


};

const btns = document.getElementsByTagName('button');

btns[0].addEventListener('click', () => {
hotSongsRequest(6452);
})
</script>
</body>
</html>

知识补充

网络请求 | AJAX

网络请求 | Fetch_API 基本用法

参考

MDN Fetch API

AJAX Introduction

axios API