前置知识点
HTTP请求方法
简单请求
预检请求
- 只有跨域的情况下,才会发生预请求
- 与前述简单请求不同,“需预检的请求”要求必须首先使用OPTIONS方法发起一个预检请求到服务器,以获知服务器是否允许该实际请求。“预检请求”的使用,可以避免跨域请求对服务器的用户数据产生未预期的影响。
withCredentials为true不会产生预请求
哪些情况下会产生预请求?
1. 请求头Content-Type为application/json会产生预请求
前端代码:
function run(){
let xhr = new XMLHttpRequest()
xhr.open('POST','http://127.0.0.1:8080/Public//testPost')
xhr.setRequestHeader('Content-Type','application/json')
xhr.onload = function(res){
console.log(res)
}
xhr.send()
}
run()
复制代码
后端代码:
public function testPost(){
header("Access-Control-Allow-Headers: Content-Type");
header("Access-Control-Allow-Origin: *");
echoJsonResult(1,'',$_POST);
}
复制代码
当后端没有配置Access-Control-Allow-Headers包含Content-Type,报错如下:
Request header field content-type is not allowed by Access-Control-Allow-Headers in preflight response.
复制代码
当后端没有配置Access-Control-Allow-Origin,报错如下
Response to preflight request doesn't pass access control check: No 'Access-Control-Allow-Origin' header is present on the requested resource.
复制代码
浏览器发出的两次请求:
- OPTIONS请求
- POST请求
2. 设置了用户自定义请求头会产生预检请求
前端代码:
let xhr = new XMLHttpRequest()
xhr.open('POST','http://127.0.0.1:8080/Public//testPost')
xhr.setRequestHeader('abc','123')
xhr.onload = function(res){
console.log(res)
}
xhr.send()
复制代码
后端代码:
public function testPost(){
header("Access-Control-Allow-Origin: *");
header('Access-Control-Allow-Headers: abc');
echoJsonResult(1,'',$_POST);
}
复制代码
OPTIONS请求的request请求头
Access-Control-Request-Headers: abc
Access-Control-Request-Method: POST
复制代码
OPTIONS请求的response响应头
Access-Control-Allow-Headers: abc
Access-Control-Allow-Origin: *
复制代码
当后端没有配置Access-Control-Allow-Headers为abc时 ,报错如下
Request header field abc is not allowed by Access-Control-Allow-Headers in preflight response.
复制代码
CORS跨域
当请求跨域,后端没有配置时,报错如下
Access to XMLHttpRequest at 'http://127.0.0.1:8080/Public//testPost' from origin 'http://10.200.137.43:8080' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource.
复制代码
则后端配置代码:
public function testPost(){
header("Access-Control-Allow-Origin: *");
echoJsonResult(1,'',$_POST);
}
复制代码
withCredentials为true时需要后端配置响应头Access-Control-Allow-Credentials为true (不会产生预请求)
前端代码:
let xhr = new XMLHttpRequest()
xhr.open('POST','http://127.0.0.1:8080/Public//testPost')
xhr.withCredentials = true
xhr.onload = function(res){
console.log(res)
}
xhr.send()
复制代码
后端代码:
public function testPost(){
header("Access-Control-Allow-Origin: http://10.200.137.43:8080");
header("Access-Control-Allow-Credentials: true");
echoJsonResult(1,'',$_POST);
}
复制代码
浏览器只发起一次POST请求:
当后端配置Access-Control-Allow-Origin为星号时,报错如下:
The value of the 'Access-Control-Allow-Origin' header in the response must not be the wildcard '*' when the request's credentials mode is 'include'.
The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
复制代码
当后端没有配置Access-Control-Allow-Credential时,报错如下
The value of the 'Access-Control-Allow-Credentials' header in the response is '' which must be 'true' when the request's credentials mode is 'include'. The credentials mode of requests initiated by the XMLHttpRequest is controlled by the withCredentials attribute.
复制代码
参考链接
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END