*uni-app之H5端跨域问题解决方案

场景:跨域问题只存在于浏览器端 ,App和小程序不存在跨域问题。

产生原因:由于uni-app是标准的前后端分离模式
开发h5应用时如果前端代码和后端接口没有部署在同域服务器,就会被浏览器报跨域。

前后端分离的开发模式越来越流行,目前绝大多数的公司与项目都采取这种方式来开发,它的好处是:
前端可以只专注于页面实现,而后端则主要负责接口开发,前后端分工明确,彼此职责分离,不再高度耦合。
但是由于这种开发模式将前后端项目分开来独立部署,所以将必不可免的会碰到跨域问题.

解决方案:uni-app官方推荐使用HBuilderX中内置的浏览器去预览,在内置的浏览器中不会存在跨域问题;
但是要是在Chrome 浏览器中预览的话就会出现这个跨域问题!官方推荐使用安装Allow-Control-Allow-Origin: * 插件的方式去解决。参考:uni-app H5跨域问题解决方案(CORS、Cross-Origin)。
拓展:在App、小程序等非H5平台,是不涉及跨域问题的。稍微例外的是iOS的wkWebview,在5+App,或uni-app的web-view组件及renderjs中,由于WKWebview限制也会产生跨域,这方面另见Appstore审核反馈废弃UIWebview APIs问题的说明。uni-app在App的普通js代码不运行在Webview下,不存在跨域问题。

那什么是跨域呢 我们来了解下!

1. 什么是跨域

跨域指浏览器不能执行其他网站的脚本。它是由浏览器的同源策略造成的(目前所有的浏览器都实行同源策略),是浏览器对javascript施加的安全限制。

同源策略:指协议、域名、端口都要相同,其中有一个不同都会产生跨域
跨域:指浏览器不能执行其他网站的脚本。(跨域限制访问,其实是浏览器的限制)

A B 分析 是否跨域
https://www.baidu.com/index.html https://www.baidu.com/index.php 同源
http://www.baidu.com/index.html https://www.baidu/index.php 协议不同(http/https)
http://www.123.com/index.php http://www.456.com/index.php 主域名不同(123/456)
https://123.baidu.com/index.html https://453.baidu.com/index.php 子域名不同(123/456)
http://www.123.com:8080/index.html http://www.123.com:8081/index.php 端口不同(8080/8081)

注意*:localhost和127.0.0.1虽然都指向本机,但也属于跨域;域名和域名对应的ip也属于跨域。

2. 调试时的跨域解决方案

前端工程师调试时,运行起来的前端代码在uni-app自带的web服务器中,而不是部署在后台业务服务器上,此时就会遇到跨域。除了协调后端配置允许跨域,其实也可以自己解决跨域问题。
共3种方案可选:

2.1 使用HBuilderX内置浏览器

内置浏览器:经过官方处理,不存在跨域问题,简单易用,推荐使用(需HBuilderX 2.6以上)。
使用:在打开页面后,点HBuilderX右上角的预览,即可打开内部浏览器;或者在运行菜单里选择运行到内置浏览器也可以。

2.2 配置webpack-dev-server代理
参考:配置指南

2.3 给浏览器安装跨域插件
(1) 当我们使用谷歌浏览器调试ajax请求的时候可能会遇到这两个问题:
跨域资源共享CORS:CORS是一种w3c标准,全称是"跨域资源共享(Cross-origin resource sharing)"。它允许浏览器向跨源服务器发出XMLHttpRequest请求,从而克服了同源使用的限制。(传统的Ajax请求只能获取在同一个域名下面的资源,但是HTML5打破了这个限制,允许Ajax发起跨域的请求。浏览器是可以发起跨域请求的,比如你可以外链一个外域的图片或者脚本;但是Javascript脚本是不能获取这些资源的内容的,它只能被浏览器执行或渲染。)
跨源读取阻塞 CORB:如果实际响应的内容与浏览器预期的内容有差异可能被CORB策略所阻止。
最常见的就是关于跨域资源共享的问题,也就是我们通常说的跨域。当我们本地服务器预览页面,使用ajax访问远程服务器的内容时就会请求失败,比如:本地预览的地址是:http://localhost:8080/,访问的接口地址是http://dcloud.io/api。

(2) 如果仅仅是为了本地预览,可以使用Chrome浏览器插件Allow-Control-Allow-Origin: *来协助调试。

本插件并非万能,请仔细阅读与学习浏览器安全策略相关知识。本插件只能解决简单请求的跨域调试;对于非简单请求的OPTION预检请求以及线上服务器也有跨域需求的用户,需要服务端配合解决。即此插件适合本地调试使用,线上部署如果和接口不同域还需要服务端配合。

(3) 插件安装方式

在线安装:在谷歌浏览器直接打开插件地址安装插件即可
离线安装:国内用户如果无法在线安装,可点击本地下载后离线安装插件
(4) 若使用插件后跨域问题依旧存在。

分析:uni-app 中 manifest.json->h5->devServer 实际上对应 webpack 的 devServer,鉴于 manifest 为 json 文件,故 webpack.config.js->devServer配置项下的简单类型属性均可在manifest.json->h5->devServer节点下配置,funciton 等复杂类型暂不支持。参考:manifest.json官方配置文档和uniapp-admin。
解决:参考使用proxy配置反向代理的方式去实现跨域请求,未验证

3. 部署时的跨域解决方案

(1) 方案1:最直接的,当然还是将前端代码和后端接口部署在同域的web服务器上

(2) 方案2:由后台服务器配置策略,设为允许跨域访问。

Access-Control-Allow-Origin是HTML5中定义的一种解决资源跨域的策略。通过服务器端返回带有Access-Control-Allow-Origin标识的Response header,用来解决资源的跨域权限问题。即在服务器响应客户端的时候,带上Access-Control-Allow-Origin头信息:

  • Access-Control-Allow-Origin: * //允许所有域名的脚本访问该资源
  • Access-Control-Allow-Origin:www.google.com //允许特定的域名访问

4. 其他

如果资源是html页面,可通过如下设置 解决跨域问题

下面展示一些 内联代码片

<meta http-equiv="Access-Control-Allow-Origin" content="*">
上一篇:cors跨域


下一篇:fetch--post--json请求报错