解决 CORS 跨域错误

造成 CORS 跨域报错的原因肯定不止一两种,但是我先归纳我遇到的
简单请求与非简单请求
我简单写了一函数,用于每次调用的时候来一张随机的小狗图片:
1 | // 该函数会引起 CORS 问题 |
引起了报错:
1 | Access to fetch at 'https://dog.ceo/api/breed/pembroke/images/random' from origin 'http://localhost:5173' has been blocked by CORS policy: Response to preflight request doesn't pass access control check: It does not have HTTP ok status. |
这句话的意思是:“预检请求(preflight request) 的响应未能通过访问控制检查:它的 HTTP 状态不是 OK”。
当你的前端代码要发送一个“非简单请求”时,浏览器会出于安全考虑,在发送真正的请求(比如你的 GET 请求)之前,自动先发送一个 OPTIONS 方法的“预检请求”到目标服务器。这个预检请求会问服务器:“我接下来要发送一个来自 http://localhost:5173 的 GET 请求,并且会带上 Content-Type: application/json 这个请求头,你允许吗?”
- 那为什么预检失败了?
GET 请求根本不需要 Content-Type 请求头,因为 GET 请求没有请求体(body)。 Content-Type 是用来描述你发送给服务器的数据格式的(比如在 POST 或 PUT 请求中)。
所以 dog.ceo 这个 API 的服务器没法响应这个 OPTIONS 预检请求。当它收到这个预检请求时,它没有返回一个成功的 HTTP 状态码(比如 200 或 204),导致浏览器认为服务器不同意接下来的操作。因此,浏览器直接阻止了你的实际 GET 请求,并抛出了这个 CORS 错误。
简单请求(Simple Request) 和 非简单请求(Non-Simple Request)
前面说到发送一个“非简单请求”时,浏览器会在发送真正的请求前,先发送一个 OPTIONS 方法的“预检请求”。
那啥是非简单请求?
-
简单请求(Simple Request) 需同时满足以下条件:
-
请求方法是 GET、HEAD 或 POST 之一。
-
HTTP 头信息不超出以下几个字段:
Accept
、Accept-Language
、Content-Language
、Content-Type
(但 Content-Type 的值仅限于application/x-www-form-urlencoded
、multipart/form-data
、text/plain
)。
-
-
非简单请求(Non-Simple Request)
- 不满足上述任一条件的请求,比如 PUT、DELETE 方法,或者包含了
Content-Type: application/json
这样的头信息。
- 不满足上述任一条件的请求,比如 PUT、DELETE 方法,或者包含了
说了这么多,解决方案呢?
解决方案非常简单:移除不必要的 headers 即可。
1 | async function getDogImage() { |
- 标题: 解决 CORS 跨域错误
- 作者: 三葉Leaves
- 创建于 : 2025-06-22 00:00:00
- 更新于 : 2025-07-10 13:40:50
- 链接: https://blog.oksanye.com/ec6616ad2d2b/
- 版权声明: 本文章采用 CC BY-NC-SA 4.0 进行许可。