加载外部资源的跨域问题

6/1/2023

# 问题的现象

浏览器提示 CORS policy 错误,所加载的底图、地形、模型等外部数据没有显示。F12 中提示 CORS 相关错误。

# 问题原因

这是资源跨域权限的错误,由于浏览器同源策略,凡是发送请求 url 的协议,域名,端口三者之间任意一个与当前页面地址不同即为跨域,存在跨域的情况:

  • 网络协议不同,如 http 协议访问 https 协议。
  • 端口不同,如 80 端口访问 8080 端口
  • 域名不同,如www.jd.com 访问 baidu.com
  • 子域名不同,如 abc.blog.com 访问 def.blog.com
  • 域名和域名对应的 ip,如www.abc.com访问20,205,28,90

Access-Control-Allow-Origin 是 HTML5 中定义的一种服务器端返回 Response header,用来解决资源(比如字体)的跨域权限问题。 它定义了该资源允许被哪个域引用,或者被所有域引用(google 字体使用*表示字体资源允许被所有域引用)。

# 解决方法及步骤

因为浏览器和 WebGL 的安全性要求,Cesium 和 Mars3D 加载的所有外部资源,都需要服务端允许跨域访问,跨域问题的终极解决方法在服务端:

  • 若服务端可控:添加跨域头
  • 若服务端不可控:添加代理服务,代理方式有很多,我们有 2 种推荐的方式:
  1. 可以使用nginx (opens new window)来代理,需要有一定 nginx 基础知识。
  2. 可以使用https://github.com/muyao1987/web-proxy (opens new window)发布的服务,并在相关代码配置 proxy 属性,来代理转发相关请求。

image

# 非跨域的类似报错问题

以下一些问题也会提示 CORS 错误,但实际原因可能不是跨域引起的。

# 问题 1:The request client is not a secure context and the resource is in more-private address space private.

Chrome 浏览器访问 mars3d 官网模型调试示例,加载本地 localhost 的服务模型时,报了这么个错:

 The request client is not a secure context and the resource is in more-private address space private.
1

这是浏览器安全机制,是谷歌 94+后,新增的功能,公网资源(访问者) 访问 私网资源(被访问者)会提示此错误。

# 解决方式

任选下面 1 种方式

  1. 配置 chrome 选项,打开浏览器,进chrome://flags/#block-insecure-private-network-requests页面 , 将Block insecure private network requests.配置项的Default改为Disabled即可

  2. 两种资源都改成 https 或 都改成内网或者外网 IP

  3. 配置Access-Control-Allow-Private-Network请求头(实际测试后,没有配置成功)

# 问题 2:瓦片 404 请求

访问影像瓦片底图时,如果瓦片不存在,也会在 404 错误后提示 CORS 错误。

# 解决方式

  1. 对瓦片配置 rectangle 参数,限定请求瓦片范围,
 {
    "name": "合肥",
    "type": "xyz",
    "url": "{dataServer}/tile/googleImg/{z}/{x}/{y}.jpg",
    "rectangle": { "xmin": 116.33236, "xmax": 118.183557, "ymin": 31.143784, "ymax": 32.565035 }
}
1
2
3
4
5
6
  1. 服务端补充缺失的瓦片数据
最后更新: 9/23/2024, 10:37:46 AM