在跨域资源共享(CORS,Cross-Origin Resource Sharing)机制中,HTTP 请求分为两类:简单请求(Simple Requests)和复杂请求(Preflighted Requests)。这两类请求有不同的处理方式和要求。
简单请求(Simple Requests)
简单请求指的是浏览器可以直接发送的请求,不需要额外的预检请求(preflight request)。这类请求的条件如下:
-
请求方法:请求方法必须是以下几种之一:
GETHEADPOST
-
请求头:请求头中只能包含以下几种头字段:
AcceptAccept-LanguageContent-LanguageLast-Event-ID(仅限于Server-Sent Events)Content-Type(仅限于以下值:application/x-www-form-urlencoded、multipart/form-data、text/plain)
-
请求体:请求体的数据类型必须是
application/x-www-form-urlencoded、multipart/form-data或text/plain。
示例:简单请求
javascript
fetch('https://api.example.com/data', {
method: 'GET',
headers: {
'Accept': 'application/json'
}
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error(error));
复杂请求(Preflighted Requests)
复杂请求指的是需要先发送一个预检请求(preflight request)来确认服务器是否允许跨域请求。预检请求是一个 OPTIONS 方法的请求,用于检查服务器是否允许后续的实际请求。
条件
如果请求不符合简单请求的条件,则被视为复杂请求。具体条件如下:
- 请求方法:除了
GET、HEAD和POST之外的方法,如PUT、DELETE等。 - 请求头:请求头中包含除上述简单请求允许的头字段之外的其他头字段,如
Authorization、Content-Type等。 - 请求体:请求体的数据类型不是
application/x-www-form-urlencoded、multipart/form-data或text/plain。
示例:复杂请求
javascript
fetch('https://api.example.com/data', {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer your-token-here'
},
body: JSON.stringify({ key: 'value' })
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error(error));
预检请求(Preflight Request)
预检请求是一个 OPTIONS 方法的请求,用于确认服务器是否允许后续的实际请求。预检请求包含以下头字段:
Access-Control-Request-Method:实际请求的方法,如PUT、DELETE等。Access-Control-Request-Headers:实际请求中包含的自定义头字段。
示例:预检请求
http
OPTIONS /data HTTP/1.1
Host: api.example.com
Access-Control-Request-Method: PUT
Access-Control-Request-Headers: Content-Type, Authorization
Origin: http://client.example.org
服务器响应预检请求时,应包含以下头字段:
Access-Control-Allow-Origin:允许的源。Access-Control-Allow-Methods:允许的方法。Access-Control-Allow-Headers:允许的头字段。Access-Control-Max-Age:缓存预检结果的时间。
示例:预检请求的响应
http
HTTP/1.1 200 OK
Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: PUT, DELETE
Access-Control-Allow-Headers: Content-Type, Authorization
Access-Control-Max-Age: 86400
总结
- 简单请求:直接发送请求,无需预检。
- 复杂请求:先发送预检请求(
OPTIONS),再发送实际请求。
通过合理配置服务器端的 CORS 设置,可以确保跨域请求的安全性和有效性。了解这两种请求的区别和处理方式,可以帮助开发者更好地处理跨域问题。