移动体验 / 方法解读

移动端 fetch 跨域请求携带 Cookie 失败如何排查

当移动端 fetch 请求携带凭证时,若服务器未返回 Access-Control-Allow-Origin 响应头,请求会因跨域策略而失败。

展示代码编辑器中设置CORS允许凭证的配置界面,包含cors_allow_credentials和cors_origin_aloow参数设置。
主题资料配图,非新闻现场照片 · 配图:设置可跨域范围 cors_allow_credentials = true cors_origin_aloow

检查服务器是否在控制范围内并配置响应头

如果目标服务器在你的控制范围内,需要在服务器配置中添加 Access-Control-Allow-Origin 响应头。对于 Apache 服务器,可以在配置文件或 .htaccess 文件中添加 Header set Access-Control-Allow-Origin 'https://example.com'。对于 Nginx 服务器,可以使用 add_header 'Access-Control-Allow-Origin' 'https://example.com' always; 指令。配置后需要重启服务器或重新加载配置。

配置时需要注意,如果需要允许携带凭证(如 Cookie),不能使用通配符 *。服务器必须读取请求的 Origin 头部并动态设置 Access-Control-Allow-Origin 的值,同时设置 Vary: Origin 头部以指示响应头是动态变化的。例如,允许 https://example.com 访问时,应设置 Access-Control-Allow-Origin: https://example.com。

使用客户端降级方案或代理服务器解决

如果无法控制目标服务器,可以尝试修改客户端请求方式。如果不需要读取响应内容,可以在 fetch() 调用中使用 mode: 'no-cors'。这样请求会成功发送,但响应将是不可读的(opaque)。这适用于埋点上报等不需要读取结果的操作。注意,使用 no-cors 模式无法携带凭证。

另一种方案是使用代理服务器。你控制一个代理服务器,由它去请求目标资源并返回带有正确 CORS 响应头的内容。客户端只与代理服务器通信,从而绕过跨域限制。这种方法需要维护代理服务,但能解决大多数跨域问题。

验证修复结果与排查步骤

修复配置后,刷新移动端页面并重新发起请求。在 Network 面板中检查响应头是否包含 Access-Control-Allow-Origin。如果配置正确,请求状态应为 200 OK,且响应头中包含允许的源。如果仍然失败,检查服务器配置是否生效,确认配置文件路径正确,且服务器已重新加载。

如果使用客户端方案,检查控制台是否有错误信息。对于 no-cors 模式,请求状态可能显示为 0 或 opaque,这是正常现象。对于代理方案,检查代理服务器日志,确认它成功获取了资源并返回了正确的响应头。确保代理服务器本身没有跨域配置问题。

理解通配符与凭证的冲突限制

在配置 Access-Control-Allow-Origin 时,通配符 * 仅适用于匿名请求,且无法携带凭证。如果需要在跨域请求中发送 Cookie,服务器必须明确指定允许的源,而不能使用 *。这要求服务器能够解析请求中的 Origin 头部,并将其动态写入响应头中。

此外,动态设置响应头时,必须配合 Vary: Origin 头部。这一指示告诉缓存服务器,该响应的内容会根据不同的源而变化,从而避免缓存错误。这是确保跨域凭证安全传输的重要配置细节。对于不在控制范围内的服务器,客户端必须通过代理或简化请求逻辑来规避这一限制。

资料与延伸阅读

你可以通过以下原始资料核对文中概念,并继续深入阅读。

  1. Reason: CORS header 'Access-Control-Allow-Origin' missing - HTTP | MDN ↗
  2. 配图:设置可跨域范围 cors_allow_credentials = true cors_origin_aloow ↗
← 更多移动体验文章返回顶部 ↑