目录CORS预检请求携带了自定义头信息的请求PUT,DELETE方法的请求服务器不允许跨域总结CORS 出于安全性,浏览器限制脚本内发起的跨源 Http 请求。例如,XMLHttpR
出于安全性,浏览器限制脚本内发起的跨源 Http 请求。例如,XMLHttpRequest
和 Fetch api
遵循。这意味着使用这些 API 的 WEB 应用程序只能从加载应用程序的同一个域请求 HTTP 资源,除非响应报文包含了正确 CORS 响应头。
跨源资源共享CORS,通过允许服务器标示除了它自己以外的其他访问源、协议或端口,使得浏览器允许这些源访问加载自己的资源。简单讲,就是目标资源与当前页面不处于同一个域时,浏览器的同源策略会阻止请求发出者获得响应数据。除非服务器允许跨域访问,也就是支持CORS。
这是一些CORS相关的响应头信息,如果目标资源服务器支持CORS,必须附带一部分这些头信息与浏览器交互
Access-Control-Allow-Origin:该字段必须出现在服务器的响应中,表示允许跨域的源。如果是通配符( * ),表示接受任意域名的请求。
Access-Control-Allow-Methods:该字段表示接受的请求方法列表,多个值用逗号分隔。
Access-Control-Allow-Headers:该字段指定了实际请求可以携带的头部信息,多个值用逗号分隔。
Access-Control-Allow-Credentials:该字段标记是否允许发送 Cookie。如果为 true,则表示允许发送 Cookie。
Access-Control-Max-Age:该字段指定了预检请求的有效期(单位为秒),即在指定时间内不再发送预检请求,直接发送实际请求即可。
Access-Control-Expose-Headers:该字段用于指定哪些头部信息可以作为响应的一部分被获取到。
当发送跨域请求时,浏览器会先发送一个OPTioNS方法的预检请求,探测服务器是否允许实际请求(POST、GET等)的跨域访问。服务器在接收到这个请求后,会返回一组响应头信息(详见上文),包含了对CORS的支持情况和允许的请求方法,如果服务器对跨域请求进行了允许,则浏览器才会真正地发送POST请求。如果服务器对预检请求的响应头中拒绝跨域访问或者根本没有任何CORS头信息,浏览器会抛出错误
因此,浏览器需要发送两次请求来确认服务器是否允许跨域请求,并确保安全性。
下面将演示触发预检请求的情况并且演示是处于跨域的环境下。
在这种情况下,无论任何请求方法都会触发预检请求
我们请求 https://api.GitHub.com/
,这个接口支持跨域访问,我们通过添加自定义请求头,来触发预检请求
代码:
var requestOptions = {
method: 'GET',
headers: {
test: 'test' // 自定义的头信息
},
redirect: 'follow'
}
fetch("https://api.github.com/", requestOptions)
.then(response => response.JSON())
.then(result => console.log(result))
.catch(error => console.log('error', error))
运行效果:
可以看到明明在代码里面只有一次请求,可是浏览器却发出了两次请求,其中一个请求就是预检请求
看下预检请求和真实请求的请求头:
不难发现
access-control-request-headers
字段标识了真实请求头中的自定义字段access-control-request-method
字段标识了真实请求所使用的方法,这里是GET方法总结来说,预检请求会携带上真实请求使用的请求方法和自定义头字段,去探测服务器是否允许这样做。
再来看下预检请求的响应头
这些用蓝色方框圈起来的字段可以在上文中找到对应的解释。这里需要说明一点,可以从第一张图看到真实请求是失败的,原因在于我们添加的自定义请求头字段test
并不在服务器允许的请求头字段中,这一点从预检请求的响应头字段access-control-allow-headers
很容易看出。
那么如果不携带test
头信息,或者换成允许的头字段,请求会成功,这一点留给读者自行测试。
PUT请求
var raw = jsON.stringify({
"selected_organization_ids": [
32,
91
]
})
var requestOptions = {
method: 'PUT',
body: raw,
redirect: 'follow'
}
fetch("https://api.github.com/enterprises//actions/runner-groups//organizations", requestOptions)
.then(response => response.text())
.then(result => console.log(result))
.catch(error => console.log('error', error))
DELETE请求
var requestOptions = {
method: 'DELETE',
redirect: 'follow'
}
fetch("https://api.github.com/admin/users//authorizations", requestOptions)
.then(response => response.text())
.then(result => console.log(result))
.catch(error => console.log('error', error))
真实请求失败是因为没有传递正确的参数或者接口需要认证。
上文的演示都是建立在目标资源允许跨域访问的基础上,下面演示目标资源不允许跨域的情况
fetch("https://buy.vmall.com/getSkuRushbuyInfo.json", {
method: 'get',
headers: {
test: 'test'
}
}).then(res => {
return res.json()
}).then(res => {
console.log(res)
})
观察到预检请求头中没有任何CORS响应头信息,表示服务器不允许跨域访问,这时候浏览器就会报错
在代码层面也是可以捕捉到错误的,但是演示代码中没有捕获。
以上就是一文详解CORS与预检请求的详细内容,更多关于CORS与预检请求的资料请关注编程网其它相关文章!
--结束END--
本文标题: 一文详解CORS与预检请求
本文链接: https://lsjlt.com/news/210968.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
2024-01-12
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
2023-05-20
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0