拓冰建站拓冰建站
首页 / 资讯中心 / 正文

uni-app 跨域(CORS)问题全解析:H5 前端跨域原理、部署与调试解决方案

示例工程前端移动开发跨平台【免费下载链接】uni-appA cross-platform framework using Vue.js项目地址https://gitcode.com/gh_mirrors/un/uni-app点击查看免费下载本篇指南系统梳理 uni-app 在 H5 平台开发中遇到的跨域CORS问题从浏览器的同源策略出发讲清跨域为何产生、App 与小程序为何天然不跨域并给出 callFunction 连接 uniCloud 云函数、前后端分离部署传统服务器以及本地调试阶段三大解决方案的完整实操步骤。读完你能够自主判断项目属于哪种跨域场景并选择内置浏览器、devServer 代理、浏览器跨域插件或服务端白名单等最适合的方案落地。什么是跨域跨域是浏览器的专用概念指 JS 代码访问自己来源站点之外的站点。例如 A 站点网页中的 JS 代码请求了 B 站点的数据就是跨域。A 和 B 要想被认为同域必须同时满足三个条件相同的协议protocol例如http与https即使域名相同也不算同域相同的域名host相同的端口号port。三者任一不同浏览器就会判定为跨域并基于同源策略拦截跨域请求的响应。uni-app 中哪些平台不涉及跨域如果你做的是App、小程序等非 H5 平台是不涉及跨域问题的。原因在于这些平台的 JS 运行环境不是浏览器没有浏览器的同源策略限制。需要特别说明的是 iOS 平台的一个例外情况iOS 的 WKWebview中。在 5App或 uni-app 的 web-view 组件及 renderjs 中由于 WKWebview 限制也会产生跨域详情参见官方专题文章。而 uni-app 在 App 的普通 JS 代码并不运行在 Webview 下因此不存在跨域问题。同样在 web-view 组件文档 中也印证了这一结论App 平台各端 Webview 对本地网页跨域策略不同Android、iOS、鸿蒙要求依次严格且 uni-app x 中 web-view 组件在鸿蒙上默认仅允许跨域访问 App 包资源访问应用沙盒文件会报不允许访问——这说明跨域限制本质上来自各平台 Webview浏览器内核自身的安全策略而非 uni-app 框架。H5 平台跨域产生的根本原因由于 uni-app 是标准的前后端分离模式开发 H5 应用时如果前端代码和后端接口没有部署在同域服务器就会被浏览器报跨域错误。这是 H5 开发中最常见也最需要解决的场景。如果前端要 callFunction 连接 uniCloud 云函数在 H5 页面里调用uniCloud.callFunction会跨域此时需要在 uniCloud 的 Web 控制台配置域名白名单被加白的域名可以跨域 callFunction详见官方 uniCloud 快速开始文档的 useInH5 章节。另外需要注意运行期间在 HBuilderX 的内置浏览器里是不存在跨域的。这为云函数联调提供了一个便利通道。如果前端要连接传统后台服务器连接传统后台服务器时需要区分部署时和调试时两种场景解决方案完全不同场景核心思路推荐方案部署时让浏览器认为前后端同域或由服务端放开跨域同域部署、服务端配置 CORS调试时在本地开发链路中消除跨域内置浏览器、devServer 代理、浏览器插件部署时的跨域解决方案部署到线上环境后跨域必须在服务端层面解决共有两个方案方案 1同域部署最利索将前端代码和后端接口部署在同域的 Web 服务器上从根源上消除跨域。这最彻底、最省心也最推荐。方案 2由后台服务器配置策略允许跨域访问当无法同域部署时例如前端页面部署在 uniCloud 的前端页面托管里但需要访问自己服务器的接口此时需要在服务端允许前端页面托管的域名跨域访问。不同服务端框架允许跨域的配置不一样这里以eggjs为例给出完整三步配置1安装egg-cors包npm i egg-cors --save2在plugin.js中设置开启 corsexports.cors { enable: true, package: egg-cors, };3在config.default.js中配置白名单config.security { domainWhiteList: [ 前端网页托管的域名 ], };将domainWhiteList中的值替换为实际托管前端页面的域名如https://xxx.static.dcloud.net.cn即可。核心原理是服务端在响应头中携带Access-Control-Allow-Origin等 CORS 头浏览器校验通过后放行跨域响应。调试时的跨域解决方案前端工程师调试时运行起来的前端代码在uni-app 自带的 Web 服务器中而不是部署在后台业务服务器上此时就会遇到跨域。除了协调后端配置允许跨域其实也可以自己解决。共 3 种方案可选方案 1使用 HBuilderX 内置浏览器推荐这个内置浏览器经过官方处理不存在跨域问题简单易用需 HBuilderX 2.6 以上。在打开页面后点击 HBuilderX 右上角的预览即可打开内部浏览器或者在运行菜单里选择运行到内置浏览器也可以。方案 2配置 devServer 代理在 uni-app 的 Web 端开发链路中项目的开发服务器基于 Vitedcloudio/vite-plugin-uni完全支持 Vite 的server.proxy代理能力。Web 端开发文档 中给出了可直接复制的配置示例在项目根目录新增vite.config.js// vite.config.js import { defineConfig } from vite; import uni from dcloudio/vite-plugin-uni; export default defineConfig({ plugins: [uni()], server: { proxy: { // 如下写法转化请求地址 // http://localhost:5173/api/ // - https://httpbin.org/ /api: { target: https://httpbin.org, changeOrigin: true, rewrite: (path) path.replace(/^\/api/, ), } }, } });开发期间将请求地址修改为/api/xxx此时请求的是网页所在地址的同源地址不存在跨域问题let base https://httpbin.org/ if(process.env.NODE_ENV development) { base /api/ // 开发期间请求/api/xxx为网页所在地址的同源地址不存在跨域问题 } uni.request({ method: POST, url: base post, success(res) { console.log(res) }, fail(err) { console.error(err) } })代理方案的核心原理浏览器侧的请求目标始终是http://localhost:5173开发服务器自身由 Vite devServer 在服务端转发到真实后端接口再原样返回。因为浏览器视角下请求始终是同源的跨域问题自然消失。该方案同样适用于uni.request与 axios 等任何基于 XHR/fetch 的请求库。方案 3给浏览器安装跨域插件禁止浏览器报跨域本插件并非万能请仔细阅读与学习浏览器安全策略相关知识。使用谷歌浏览器调试 ajax 请求时可能会遇到两个问题跨域资源共享CORS最常见即通常说的跨域。当本地服务器预览页面使用 ajax 访问远程服务器内容时请求失败。例如本地预览地址是http://localhost:8080/访问的接口地址是http://dcloud.io/api跨源读取阻塞CORB浏览器基于内容类型对响应做进一步校验时的拦截。如果仅仅是为了本地预览可以使用 Chrome 浏览器插件协助调试。注意插件只能解决简单请求的跨域调试对于非简单请求的 OPTION 预检Preflight请求以及线上服务器也有跨域需求的场景必须由服务端配合解决。Chrome 插件名称Allow-Control-Allow-Origin: *安装方式在线安装使用 Chrome 浏览器打开插件商店中该插件页面直接安装离线安装国内用户无法在线安装时下载得到Allow-Control-Allow-Origin.crx点击浏览器右上角的菜单按钮打开谷歌浏览器的扩展管理页面将下载的扩展插件拖入扩展管理页面。使用方式打开待调试的页面在扩展栏目找到安装的插件点击打开插件配置输入想要进行跨域调试的接口地址点击添加即可。注意事项此插件适合本地调试使用线上部署如果与接口不同域仍需要服务端配合如果实际响应的内容与浏览器预期的内容有差异还可能被CORB策略所阻止Firefox 也有对应的跨域插件注意 Firefox 的 CSS 兼容问题。其他历史问题HBuilderX 2.3.0 版在某些情况下会报跨域请升级到 2.3.1 解决。当前版本远高于此正常更新 HBuilderX 即可规避该历史缺陷。跨域请求中的关键配置项withCredentials除了解决能否跨域还常遇到跨域时能否携带凭证的问题。uni.request 的 API 文档 中给出了相关配置项参数类型默认值平台支持说明withCredentialsbooleanWeb、微信小程序等跨域请求时是否携带凭证cookies当服务端 CORS 配置为Access-Control-Allow-Origin: *时浏览器通常不允许携带凭证若业务需要跨域携带 Cookie服务端必须返回明确的Access-Control-Allow-Credentials: true且前端需将withCredentials置为true两者缺一不可。这也是生产环境跨域联调中最常踩的坑之一。总结跨域解决决策表你的场景首选方案备选方案App、小程序非 H5无需处理注意 iOS WKWebview / web-view 组件内部页面H5 连接 uniCloud 云函数uniCloud 控制台配置域名白名单HBuilderX 内置浏览器调试H5 部署可同域前后端同域部署服务端配置 CORSH5 部署非同域服务端配置 CORS 白名单如 egg-cors云函数/网关层统一处理H5 本地调试HBuilderX 内置浏览器Vite devServer 代理 / 浏览器跨域插件跨域携带 Cookie服务端Access-Control-Allow-Credentials 前端withCredentials: true改为同域部署跨域问题贯穿 H5 开发的全生命周期。理解同协议 同域名 同端口的同源三要素再按部署靠服务端、调试靠本地工具的原则分场景处理即可在 uni-app 项目中彻底绕开 CORS 的干扰让前后端联调顺畅推进。赞分享示例工程前端移动开发跨平台【免费下载链接】uni-appA cross-platform framework using Vue.js项目地址https://gitcode.com/gh_mirrors/un/uni-app点击查看免费下载创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门