解决 CORS 跨域错误

三葉Leaves Author

造成 CORS 跨域报错的原因肯定不止一两种,但是我先归纳我遇到的

简单请求与非简单请求

我简单写了一函数,用于每次调用的时候来一张随机的小狗图片:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 该函数会引起 CORS 问题
async function getDogImage(){
try {
const data = await fetch('https://dog.ceo/api/breed/pembroke/images/random', {
method: 'GET',
headers: {
// 问题就出在这一行
'Content-Type': 'application/json',
'Accept': 'application/json',
}
})
if (!data.ok) throw new Error('HTTP 错误' + data.status)
const url = (await data.json()).message
console.log(url)
} catch (e) {
console.error(e)
}
}

引起了报错:

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 头信息不超出以下几个字段:AcceptAccept-LanguageContent-LanguageContent-Type(但 Content-Type 的值仅限于 application/x-www-form-urlencodedmultipart/form-datatext/plain)。

  • 非简单请求(Non-Simple Request)

    • 不满足上述任一条件的请求,比如 PUT、DELETE 方法,或者包含了 Content-Type: application/json 这样的头信息。

说了这么多,解决方案呢?

解决方案非常简单:移除不必要的 headers 即可。

1
2
3
4
5
6
7
8
9
10
async function getDogImage() {  
try {
const data = await fetch('https://dog.ceo/api/breed/pembroke/images/random')
if (!data.ok) throw new Error('HTTP 错误' + data.status)
const url = (await data.json()).message
console.log(url)
} catch (e) {
console.error(e)
}
}
  • 标题: 解决 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 进行许可。
评论