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页面资源,如果a、b页面的协议、域名、端口、子域名不同,所进行的访问行动都是跨域的,而浏览器为了安全问题一般都限制了跨域访问,也就是不允许跨域请求资源。

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

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

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

(1) 方案1:最直接的,当然还是将前端代码和后端接口部署在同域的web服务器上。
(2) 方案2:由后台服务器配置策略,设为允许跨域访问。
Access-Control-Allow-Origin是HTML5中定义的一种解决资源跨域的策略。通过服务器端返回带有Access-Control-Allow-Origin标识的Response header,用来解决资源的跨域权限问题。即在服务器响应客户端的时候,带上Access-Control-Allow-Origin头信息:

如PHP添加响应头信息:header("Access-Control-Allow-Origin: *");

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

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

3.1 使用HBuilderX内置浏览器

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

3.2 配置webpack-dev-server代理

参考:配置指南

3.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) 若使用插件后跨域问题依旧存在。

5. 其他

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

<meta http-equiv="Access-Control-Allow-Origin" content="*">
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容