移动体验 / 方法解读

移动端 fetch 请求报错 CORS request not HTTP 怎么排查

移动端 fetch 请求报错 CORS request not HTTP 通常是因为使用了 file:// 协议或非 HTTP/HTTPS 协议,请检查请求地址是否为本地文件路径。

展示代码编辑器中编写fetch跨域请求的示例代码界面
主题资料配图,非新闻现场照片 · 配图:fetch 跨域该怎么写?

检查请求地址是否使用了本地文件协议

移动端开发调试时,开发者常直接双击打开 HTML 文件,此时浏览器会使用 file:// 协议加载页面。fetch 请求若指向同目录下的资源,也会默认使用 file:// 协议。根据 MDN 资料,CORS 请求仅支持 HTTP 或 HTTPS URL scheme,file:// 协议不在支持范围内。浏览器会因此拦截请求并报错。排查时需确认 fetch 的 URL 是否包含 file:// 前缀,若存在则需修改为网络地址或本地服务器地址。

除了 file:// 协议,若请求地址使用了其他非 HTTP/HTTPS 协议(如 ws:// 或 ftp://),同样会触发此错误。例如 WebSocket 连接或 FTP 资源请求在 fetch 中使用也会报错。检查代码中的 URL 字符串,确保其以 http:// 或 https:// 开头。若资源位于本地,应搭建本地服务器(如使用 Python 的 http.server 或 Node.js 的 http-server),通过 localhost 访问,这样所有资源均使用 http:// 协议,符合 CORS 规范。

确认浏览器是否将本地文件视为跨域源

在旧版本的浏览器中,同目录下的本地文件被视为同源,加载时不会触发 CORS 错误。然而,出于安全考虑,许多现代浏览器(包括 Firefox 和 Chrome)已将所有本地文件视为具有不透明源(opaque origins)。这意味着即使资源在同一目录,浏览器也会将其视为跨域请求。MDN 指出,这种变更是为了应对安全漏洞(如 CVE-2019-11730)。因此,在移动端调试时,直接打开本地 HTML 文件加载资源极大概率会失败。

若在移动端模拟器或真机上测试,且页面是通过本地服务器(如 localhost)访问,则所有文件共享 scheme 和 domain,属于同源。此时加载本地资源不会触发 CORS 错误。若仍报错,需检查是否在代码中显式指定了非 HTTP/HTTPS 的 URL。例如,某些动态生成的 URL 可能包含错误的协议头。确保所有涉及 fetch、XMLHttpRequest、Web Fonts 等跨域操作的 URL 均为 HTTP 或 HTTPS。

使用 HTTPS 协议解决跨域请求限制

对于生产环境或需要跨域加载的资源,必须使用 HTTPS 协议。MDN 明确建议,在涉及 CORS 的请求中(如 fetch、XMLHttpRequest、Web Fonts、WebGL 纹理和 XSL 样式表),应确保使用 HTTPS URL。HTTPS 不仅符合安全标准,还能避免因协议不匹配导致的请求失败。移动端浏览器通常对 HTTP 资源有更严格的限制,使用 HTTPS 可提升兼容性。

若资源托管在第三方服务器,需确认其是否支持 HTTPS。若仅支持 HTTP,可尝试配置服务器重定向或使用代理服务。对于本地开发,使用 HTTPS 服务器(如使用 mkcert 生成本地证书)可以模拟生产环境,避免因协议差异导致的测试失败。确保所有请求的 URL 均以 https:// 开头,且服务器正确配置了 CORS 响应头(如 Access-Control-Allow-Origin)。

验证修复后的请求是否正常

修复协议问题后,需验证请求是否成功。在移动端浏览器开发者工具的 Network 面板中,查看请求的 Status Code 是否为 200 或 206,且 Type 为 fetch 或 xhr。若仍报错,检查响应头是否包含 Access-Control-Allow-Origin。若使用本地服务器,确保服务器日志显示请求已成功处理。若资源为字体或图片,可在页面中检查其是否正常显示。

若问题依旧,可尝试清除浏览器缓存并重新加载页面,确保没有旧的本地文件缓存干扰。对于 WebGL 纹理或 XSL 样式表等特殊资源,需确认其 URL 格式正确且服务器支持相应 MIME 类型。通过对比修复前后的 Network 面板记录,确认请求已从 file:// 协议切换至 http:// 或 https:// 协议,且无 CORS 错误。

资料与延伸阅读

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

  1. Reason: CORS request not HTTP - HTTP | MDN ↗
  2. 配图:fetch 跨域该怎么写? ↗
← 更多移动体验文章返回顶部 ↑