一文说尽 CORS

本文详细介绍了CORS(跨域资源共享)的工作原理,包括什么是跨域请求、预检请求的触发条件及处理、非预检请求的CORS处理,以及与之相关的响应头和跨域时携带Cookie的限制。通过对CORS机制的理解,有助于解决前端开发中的跨域问题。
摘要由CSDN通过智能技术生成

CORS的英文全称是"Cross-Origin Resource Sharing"。代表“跨域资源共享”,是一种用于在Web浏览器和Web服务器之间共享跨域资源的机制。跨域资源是指来自不同域的网页上的资源,如字体,图像,脚本和样式表等。CORS允许网站服务器提供一组规则,以确定哪些网站可以访问其资源。

1.什么是跨域请求

跨域请求是指从一个Web页面发出的请求,而且其目标资源与当前页面不同源。

同源是指协议、域名和端口号都相同,而不仅仅是域名相同。

如果使用的协议、端口或域名有一个不同,它们就被视为不同源,默认不可以进行跨域访问。

2.预检(Preflight)请求

顾名思义,预检请求用来检查实际请求是否安全可行,确保接下来的实际请求不会引起安全问题。

浏览器会在发送预检请求之后等待响应,只有当服务器允许时,才会发送实际请求。

2.1 什么情况下会触发预检请求

预检请求的反义词是简单请求,我们可以看下简单请求的判断标准

若请求满足所有下述条件,则该请求是简单请求:

请求方法使用下列方法之一:

  • GET

  • HEAD

  • POST

允许手动设置的标头字段为:

  • Accept

  • Accept-Language

  • Content-Language

  • Content-Type(需要注意额外的限制)

  • Range(只允许简单的范围标头值 如 bytes=256- 或 bytes=127-255)

Content-Type 标头的值仅限于下列三者之一:

  • text/plain

  • multipart/form-data

  • application/x-www-form-urlencoded

XMLHttpRequest.upload 对象属性上没有注册任何事件监听器

也就是说,没有调用 xhr.upload.addEventListener(),以监听上传请求。

请求中没有使用 ReadableStream 对象。

如果不满足上述任何一个条件,都会触发预检请求

2.2 预检请求的CORS处理

在CORS中,预检请求的目的是用于检查跨域请求是否安全、可行。

预检请求是在正式的跨域请求之前发起的一次探测,用于告知服务器,实际发送的跨域请求是否合法。

因此,对于预检请求的处理,需要服务器端进行相应的配置。

预检请求的处理步骤如下:

  • 浏览器会先发送一个OPTIONS请求(预检请求),包含了实际发送的跨域请求所需要的一些头信息,比如请求方法、请求头等。

  • 服务器收到后,会根据请求头中的信息进行判断,判断跨域请求是否安全可行。

  • 如果跨域请求合法,服务器会返回带有特定CORS响应头的响应,告知浏览器实际发送的跨域请求是合法的。

  • 浏览器接收到服务器的响应后,会检查响应头中的"CORS"信息。如果CORS响应头合法,则浏览器会发送实际的跨域请求,否则会抛出跨域错误,请求无法成功。

2.3 非预检请求的CORS处理

对于非预检请求,CORS会按照以下规则进行处理:

  • 如果响应头中没有包含"Access-Control-Allow-Origin",或者它的值不包含当前域名,则浏览器会抛出一个跨域错误,请求无法成功。

  • 如果响应头中包含"Access-Control-Expose-Headers",则该响应头中列出的头信息可以被前端JavaScript访问。否则,这些头信息将被浏览器拦截,无法被前端JavaScript访问。

  • 需要注意的是,虽然非预检请求不需要发送OPTIONS请求,但仍然需要服务器返回合法的CORS响应头信息。

3.跨域有关的响应头

下面列出了和跨域有关的响应头:

  • Access-Control-Allow-Origin:哪些源可以访问该资源。"*"表示所有的源都可以访问该资源。

  • Access-Control-Allow-Credentials:是否允许发送Cookie。

  • Access-Control-Expose-Headers:哪些响应头可以被前端JavaScript访问。默认情况下,不允许访问

  • Access-Control-Allow-Methods:哪些HTTP请求方法允许跨域访问。默认情况下,只允许GET、HEAD、POST方法。

  • Access-Control-Allow-Headers:允许的请求头信息。默认情况下,只允许常见的请求头,Accept、Accept-Language、Content-Language、Content-Type。

  • Access-Control-Max-Age:预检请求的有效期,单位为秒。有效期内,浏览器无需再次发送预检请求。

4.跨域和cookie

如果需要在跨域请求中携带 Cookie,服务器需要设置响应头"Access-Control-Allow-Credentials"为true

同时前端需要设置请求头"withCredentials"为true,否则无法携带 Cookie。

4.1 携带cookie时的限制

在跨域请求中携带Cookie时,浏览器会先发送OPTIONS预检请求,以检查是否允许跨域请求。

与不携带Cookie的情况相比,携带Cookie时"Access-Control-Allow-Origin"字段的限制更加严格:

  • 字段不能为通配符*,否则浏览器会忽略"Access-Control-Allow-Credentials"字段的值,不会发送Cookie。

  • 字段的值必须与请求头中"Origin"字段的值完全相同。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

afan_coding

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值