关于预请求
开头
最近学习Node,试着用node来学习一些关于后端的知识,帮助自己更好的理解web开发整个开发体系,这里总结遇到的一些坑
正文
问题
当后端设置了允许跨域的时候,前端发送请求时设置了请求头 ‘Content-Type’: ‘application/json’的时候,请求发送不成功
如图
这时的代码
- 前端
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15fetch('http://localhost:3000/', {
method: 'PUT',
headers: {
'Content-Type': 'application/json'
},
body: {
name: 'shuaxin'
}
})
.then(res => {
return res.json()
})
.then(data => {
console.log(data)
}) - 后端
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21const connect = require('connect')
const app = connect()
app
.use((req, res, next) => {
// 设置允许的请求的域名
res.setHeader("Access-Control-Allow-Origin", "*")
// 设置允许跨域请求的方法类型
res.setHeader("Access-Control-Allow-Methods", "DELETE,PUT,POST,GET,OPTIONS")
console.log(req.method);
next()
})
.use((req, res) => {
res.end(JSON.stringify({
msg: 'succ'
}))
})
app.listen('3000', () => {
console.log('服务启动')
})
解决
- 只需要在后端在设置一下跨域允许的请求头即可,代码
1
2
3....
res.setHeader('Access-Control-Allow-Headers', "Content-Type")
....
分析
在没有添加允许的请求头之前,在后台打印一下请求的method
发现并不是请求中设置的PUT,这就是浏览器的预请求机制
铺垫
这里牵扯到一个概念:简单请求和复杂请求,对于2者的区分
简单请求
- 请求方法只能是GET/POST/HEADE
- 请求头只能是:Accept/Accept-Language/Conent-Language/Content-Type 等
- 请求头的Content-Type只能是: text/plain、multipart/form-data 或 application/x-www-form-urlencoded
复杂请求(即出现预请求的条件)
- 不满足上述条件后,就成了复杂请求,也就出现了所谓的预请求发送的问题
- 分析第一张图发现请求类型的内容是 application/json,所以出现了预请求
总结
什么是预请求?目的是什么?
- 即options请求,是浏览器在我们真实的请求之前自动发送的一个请求
- 目的是为了判断服务端是否允许我们真实的请求的请求头格式、请求类型等
区分简单/复杂请求
- 就是HTML表单配合enctype可以指定的编码格式发送的请求就是简单请求
- 其他像PUT/DELETE,和需要自定义请求头设置编码格式的请求就都是复杂请求
- 查这方面知识看到奇舞周刊的一篇文章中提到的
参考
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!