子域名配置CORS后还是跨域,到底哪里错了?

Air-建利 阅读 64

我们主站是 example.com,API 服务部署在 api.example.com。我在后端设置了 Access-Control-Allow-Origin: https://example.com,但前端从 example.com 发起请求时依然报 CORS 错误,说 origin 不被允许。

试过把 credentials 设成 true,也加了 withCredentials,但没用。是不是子域名和主域名之间还有啥坑?

<script setup>
import axios from 'axios'

axios.defaults.withCredentials = true

const fetchData = async () => {
  try {
    const res = await axios.get('https://api.example.com/user')
    console.log(res.data)
  } catch (err) {
    console.error(err)
  }
}
</script>
我来解答 赞 8 收藏
二维码
手机扫码查看
2 条解答
Newb.雅涵
前端这块确实有时候挺坑爹的。你遇到的问题主要是 CORS 设置上可能有点小问题。即使子域名和主域名看起来很像,但在浏览器眼里它们是不同的 origin。所以你需要确保后端对 Access-Control-Allow-Origin 的设置是正确的。

首先,确保你的后端配置里 Access-Control-Allow-Originhttps://example.com 而不是 https://api.example.com,因为你是从 example.com 发起的请求。但是,如果你需要支持多个子域名,可以考虑使用通配符或者动态设置这个头信息,不过通配符在需要携带凭证的情况下是不行的。

其次,既然你在前端设置了 withCredentials 为 true,后端也需要相应地设置 Access-Control-Allow-Credentials 为 true。注意,设置了 Access-Control-Allow-Credentials 后,Access-Control-Allow-Origin 就不能用通配符 *,必须指定具体的源,也就是 https://example.com

最后,确保你的服务器还正确设置了 Access-Control-Allow-MethodsAccess-Control-Allow-Headers,特别是在预检请求(OPTIONS 方法)的时候。

举个例子,你的后端响应头大致应该是这样的:
Access-Control-Allow-Origin: https://example.com
Access-Control-Allow-Credentials: true
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization


这样应该能解决你的 CORS 问题。记得检查一下网络请求的详细信息,看具体的错误提示是什么,有时候浏览器会给出一些有用的线索。
点赞
2026-03-25 04:00
极客熙恩
遇到这种情况,确实有点蛋疼。子域名和主域名之间默认是不共享 cookies 和 headers 的,所以即使你设置了 Access-Control-Allow-Origin,浏览器还是会因为凭证问题拒绝请求。

首先确保你的 API 服务器上正确设置了 CORS 头。你需要允许 https://example.com 并且设置 Access-Control-Allow-Credentials 为 true。代码大致如下:

header("Access-Control-Allow-Origin: https://example.com");
header("Access-Control-Allow-Credentials: true");


然后在你的前端代码里,你已经设置了 withCredentials 为 true,这部分是对的。

不过,还有一点需要注意的是,浏览器会先发送一个预检请求(OPTIONS 方法),检查是否允许真正的请求。确保你的服务器能够正确响应这个预检请求。通常你需要在服务器端添加类似以下的处理:

if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
header("Access-Control-Allow-Headers: Content-Type");
exit(0);
}


如果以上都设置正确了,但问题依旧存在,可能需要检查你的服务器配置,比如 Nginx 或 Apache 的相关设置,有时候这些配置会覆盖掉 PHP 设置的头信息。

如果懒得自己搞这些配置,插件也可以,比如 WordPress 上有个叫 "CORS" 的插件,可以帮你快速设置好这些头信息,但记得检查一下插件的安全性和更新情况。
点赞
2026-03-21 20:09