对比ajax
优势
- promise封装,更灵活简洁
- 支持service workers,应用面更广
- fetch的promise只要请求正常执行就不会reject,如果返回码不在200-299之间时ok属性为false
服务器代码
const express = require('express');
const app = new express();
app.listen(8888, () => {
console.log('listen 8888');
});
app.get('/', (req, res) => {
res.cookie('name', 'hdy');
res.send(`
<body>
<div>首页</div>
<script>
setTimeout(() => {
fetch('http://localhost:8888/data')
.then(res => res.json())
.then(res => console.log(res));
}, 2000);
</script>
</body>
`)});
app.get('/data', (req, res) => {
res.send({name: '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
fetch()
入参1
fetch('http://localhost:8888/data')
.then(res => res.json())
.then(res => console.log(res.data));
1
2
3
app.get('/data', (req, res) => {
res.send({data: '我是/data的返回数据'});
})
1
2
3
const req = new Request('http://localhost:8888/data', {
method: 'POST',
body: JSON.stringify({name: 'hdy'}),
headers: {'Content-Type': 'application/json'}
})
fetch(req).then(res => res.json())
.then(res => console.log(res.age))
1
2
3
4
5
6
7
const bdParser = require('body-parser');
app.use(bdParser.urlencoded({extenable: false}));
app.use(bdParser.json());
app.post('/data', (req, res) =>{
const name = req.body.name;
const age = name === 'hdy' ? 18 : 0;
res.send(JSON.stringify({age}));
})
1
2
3
4
5
6
7
8
入参2
可选值
key | 作用 | 例 |
method | 请求方法 | GET |
headers | 请求的头信息,可以是Headers对象 | {'Content-Type': 'application/json'} |
body | 请求体,可以是USVstring | document | FormData | Blob | URLSearchParams | JSON.stringify({name: 'hdy'}) |
mode | 请求的模式 | cors | no-cors | same-origin |
credentials | 在当前域名内自动发送 cookie , 跨域必须提供这个选项 | omit | same-origin | include |
cache | cache模式 | default | no-store | reload | no-cache | force-cache | only-if-cached |
redirect | redirect 模式: | follow (自动重定向), error (如果产生重定向将自动终止并且抛出一个错误), 或者 manual (手动处理重定向) |
referrer | 一个USVstring | no-referrer | client【默认】| URL |
referrerPolicy | HTTP头部referer字段的值 | no-referrer | no-referrer-when-downgrade | origin | origin-when-cross-origin | unsafe-url |
integrity | 包括请求的subresource integrity | sha256-BpfBw7ivV8q2jLiT13fxDYAe2tJllusRSZ273h2nFSE=) |
- 默认是'get',传表单用post,传文件用put
fetch('http://localhost:8888/data', {
method: 'POST'
}).then(res => res.json())
.then(res => console.log(res))
1
2
3
4
app.post('/data', (req, res) =>{
console.log('post调用');
res.send({});
})
app.get('/data', (req, res) =>{
console.log('get调用');
res.send();
})
1
2
3
4
5
6
7
8
9
10
- 传表单需要改headers的 Content-Type
- 服务器解析body需要【body-parser】
fetch('http://localhost:8888/data', {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({name:'hdy'})
})
.then(res => res.json())
.then(res => console.log(res));
1
2
3
4
5
6
7
const bdParser = require('body-parser');
app.use(bdParser.urlencoded({extenable: false}));
app.use(bdParser.json());
app.post('/data', (req, res) => {
const name = req.body.name;
res.send({data: `你不是${name},你是张三`});
})
1
2
3
4
5
6
7
fetch('http://localhost:8888/data', {
mode: 'no-cors'
})
.then(res => res.json())
.then(res => console.log(res));
1
2
3
4
5
app.get('/data', (req, res) => {
res.redirect('http://localhost:8889');
})
1
2
3
4
const express = require('express');
const cookieParser = require("cookie-parser");
const app = new express();
app.use(cookieParser());
app.listen(8889, () => {
console.log('listen 8889');
});
const allowCors = function(req, res, next) {
res.header('Access-Control-Allow-Origin', req.headers.origin);
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type');
res.header('Access-Control-Allow-Credentials','true');
next();
};
app.use(allowCors);
app.get('/', function(req, res) {
res.send({data: '跨域资源666'});
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
- 不提供的情况下同源默认携带cookies,不同源不携带cookies
- exoress写入res.cookie()不需要插件,读取req.cookies需要【cookie-parser】
- 不提供,跨域请求
fetch('http://localhost:8889/data')
.then(res => res.json())
.then(res => fetch('http://localhost:8889/data2'))
.then(res => res.json())
.then(res => console.log(res))
1
2
3
4
5
const express = require('express');
const app = new express();
app.listen(8889, () => {
console.log('listen 8889');
});
const allowCors = function(req, res, next) {
res.header('Access-Control-Allow-Origin', req.headers.origin);
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type');
res.header('Access-Control-Allow-Credentials','true');
next();
};
app.use(allowCors);
const cookieParser = require('cookie-parser');
app.use(cookieParser());
app.get('/data', (req, res) => {
res.cookie('name', 'zs');
res.send({});
})
app.get('/data2', (req, res) => {
const name = req.cookies.name;
console.log(name);
res.send({name});
})
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
- 如果服务器端要新增cookie也必须设置这个属性
- 跨域请求
fetch('http://localhost:8889/data',{
credentials: 'include'
})
.then(res => res.json())
.then(res => fetch('http://localhost:8889/data2',{
credentials: 'include'
}))
.then(res => res.json())
.then(res => console.log(res))
1
2
3
4
5
6
7
8
9
fetch('http://localhost:8888/data')
.then(res => res.json())
.then(res => console.log(res))
1
2
3
app.get('/data', (req, res) => {
res.redirect('/data2');
})
app.get('/data2', (req, res) => {
res.send({data: '我是重定向的数据22'});
})
1
2
3
4
5
6
fetch('http://localhost:8888/data',{
redirect: 'manual'
})
.then(res => console.log(res))
1
2
3
4
5
app.get('/data', (req, res) => {
res.redirect('/data2');
})
app.get('/data2', (req, res) => {
res.send({data: '我是重定向的数据22'});
})
1
2
3
4
5
6
上传数据
- 将对象转化为json -> post发到后端 -> 后端存储数据
const express = require('express');
const app = new express();
app.listen(8888,() => {
console.log('listen 8888');
});
app.get('/', (req, res) => res.send(`
<body>
<div>首页</div>
<script>
let user = {
name: 'hdy',
age:18
};
setTimeout(() => {
fetch('http://localhost:8888/data', {
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(user),
method: 'POST'
})
.then(res => res.json())
.then(res => console.log(res));
}, 2000);
</script>
</body>
`));
const bdParser = require('body-parser');
app.use(bdParser.urlencoded({extended: false}));
app.use(bdParser.json());
const fs = require('fs');
app.post('/data' , (req, res) => {
const user = '\n' + JSON.stringify(req.body);
console.log(user);
fs.appendFileSync('./database.json', user, "utf-8");
res.send({data: '上传成功'});
})
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
Request
构造
Request
- 作用:创建一个新的Request请求对象
- 调用:new Request(input[, options])
- 入参:url | Request[, Object]
- tip:入参同fetch()入参
const req = new Request('http://localhost:8888/data',{
redirect: 'error'
});
fetch(req)
.then(res => res.json())
.then(res => console.log(res))
1
2
3
4
5
6
app.get('/data', (req, res) => {
res.redirect('/data2');
})
app.get('/data2', (req, res) => {
res.send({data: '我是重定向的数据22'});
})
1
2
3
4
5
6
方法
blob
- 作用:解析blob文件
- tip:blob代表一个不可变、原始数据的类文件对象
- 调用:request.blob()
- 返回:promise
fromData
- 作用:当请求体是formData时进行读取解析
- 调用:request.fromData().then()
- 返回:promise
json
- 作用:当请求体是json数据时进行读取解析
- 调用:request.json().then()
- 返回:promise
text
- 作用:当请求体是String时进行读取解析
- 调用:request.text().then()
- 返回:promise
Response
属性
Response的属性
属性 | 作用 |
body | 响应体的流读取【readableString对象】 |
headers | headers对象 |
status | 响应状态码 |
ok | 布尔值,响应状态码是否在【200-299】之间 |
redirected | 是否是重定向的结果 |
statusText | 与状态代码相对应的状态消息 |
type | 响应类型(很多浏览器未实现) |
url | 最终返回的服务器url【无论经过多少重定向】 |
fetch('http://localhost:8888/data',{
mode: 'cors'
}).then(res => {
console.log(res.body);
console.log(res.headers);
console.log(res.status);
console.log(res.ok);
console.log(res.redirected);
console.log(res.statusText);
console.log(res.type);
console.log(res.url);
})
1
2
3
4
5
6
7
8
9
10
11
12
app.get('/data', (req, res) => {
res.redirect('http://localhost:8889');
})
1
2
3
const express = require('express');
const app = new express();
app.listen(8889, () => {
console.log('listen 8889');
});
const allowCors = function(req, res, next) {
res.header('Access-Control-Allow-Origin', req.headers.origin);
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE,OPTIONS');
res.header('Access-Control-Allow-Headers', 'Content-Type');
res.header('Access-Control-Allow-Credentials','true');
next();
};
app.use(allowCors);
app.get('/', (req, res) => {
res.send({data: '跨域数据'});
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
方法
Response的方法
方法 | 作用 |
clone | 将响应对象克隆 |
error | 返回包含网络错误信息的新Response对象 |
json | 读取response的数据流并resolve一个JSON.parse的对象 |
text | 读取返回流并resolve文本 |
redirect | 返回重定向的response【service worker使用】 |
formData | 读取的数据流并resolve一个FormData对象【service worker使用】 |
arrayBuffer | 返回一个Promise.resolve(ArrayBuffer对象) |
blob | 返回一个Promise.resolve(Blob对象) |
const express = require('express');
const app = new express();
app.listen(8888, () => {
console.log('listen 8888');
});
app.get('/', (req, res) => {
res.cookie('name', 'hdy');
res.send(`
<body>
<div>首页</div>
<script>
setTimeout(() => {
fetch('http://localhost:8888/json')
.then(res => res.json())
.then(res => console.log(res)); // 我是hdy
fetch('http://localhost:8888/text')
.then(res => res.text())
.then(res => console.log(res)); // {name: 'hdy', age: 18}
}, 2000);
</script>
</body>
`)});
app.get('/text', (req, res) => {
res.send('我是hdy');
})
app.get('/json', (req, res) => {
res.send({name: 'hdy', age: 18});
})
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
Headers
方法 | 作用 |
append | 追加键值对 |
delete | 删除键值对 |
entries | 返回键值对的iterator |
get | 查找值 |
set | 设置值 |
has | 是否含有值 |
keys | 键iterator |
values | 值iterator |
set 和 append 的区别
对于已经存在的属性,append会追加,set会修改
const express = require('express');
const app = new express();
app.listen(8888, () => {
console.log('listen 8888');
});
app.get('/', (req, res) => {
res.cookie('name', 'hdy');
res.send(`
<body>
<div>首页</div>
<script>
setTimeout(() => {
const headers = new Headers({
"Content-Type": "application/json"
});
headers.set('name', 'hdy');
fetch('http://localhost:8888/text', {headers})
.then(res => res.text())
.then(res => console.log(res)); // 我是hdy
}, 2000);
</script>
</body>
`)});
app.get('/text', (req, res) => {
console.log(req.header('name'));
res.send('我是hdy');
})
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