详解nginx代理天地图做缓存解决跨域问题

作为一个GISer开发者,天地图是经常在项目中以底图的形式出现,其加载地址如:

1.天地图矢量:http://t{0-6}.tianditu.com/DataServer?T=vec_w&x={x}&y={y}&l={z}
2.天地图影像:http://t{0-6}.tianditu.com/DataServer?T=img_w&x={x}&y={y}&l={z}
3.天地图地形:http://t{0-6}.tianditu.com/DataServer?T=ter_w&x={x}&y={y}&l={z}

其中t{0-6}是天地图提供的7个服务器名称t0,t1,t2....

下面是我以openlayers加载天地图过程中遇到跨域问题

1、错误的产生条件

// 采用openlayers加载天地图
var layer = new ol.layer.Tile({
  source: new ol.source.XYZ({
    // crossOrigin: 'Anonymous', // 是否请求跨域操作
    url: url // 天地图地址
  })
});

如果没有用到crossOrigin属性就不会产生跨域问题,一般这个参数也不会设置。

这个参数使用场景如下官网所述:

The crossOrigin attribute for loaded images. Note that you must provide a crossOrigin value if you are using the WebGL renderer or if you want to access pixel data with the Canvas renderer. See https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image for more detail.

查阅MDN文档(https://developer.mozilla.org/zh-CN/docs/Web/HTML/CORS_settings_attributes),可以发现crossOrigin有两个取值

在开发过程中,往往需要本地运行开发版,服务器运行生产版。当两个版本在同一个浏览器中访问时,设置了crossOrigin就会出现跨域问题,如下图所示的错误,

has been blocked by CORS policy: No 'Access-Control-Allow-Origin'header is present on the requested resource.

注:只有天地图设置了crossOrigin之后会出现这个问题,谷歌底图是不会出现的,原因是:

天地图在返回的request header的Origin属性设置成当前访问的IP,而google底图Origin属性设置的是*,意味着不同IP的系统在浏览器缓存了google瓦片之后依然能访问google底图。

2、错误解决的方法

2.1 简单暴力的方法

简单暴力的解决方法就是清除浏览器的缓存图片,在同一时刻,只查看一个其中的一个系统,如果要查看另一个系统,必须事先清除浏览器图片缓存

2.2 删除CrossOrigin属性

重新审视一遍地图需求,判断是否真的需要crossOrigin属性,如果不需要,就根本不会出现这个问题

2.3 nginx代理解决

如果前面的方法都感觉不合适,那就用nginx来代理解决吧,它可以解决跨域问题,也可以将瓦片缓存至本地,加快访问速度。

直接上配置文件哈。

#user nobody;
worker_processes 4;

#error_log logs/error.log;
#error_log logs/error.log notice;
#error_log logs/error.log info;

#pid    logs/nginx.pid;

events {
  worker_connections 1024;
}

http {
  include    mime.types;
  default_type application/octet-stream;

  #log_format main '$remote_addr - $remote_user [$time_local] "$request" '
  #         '$status $body_bytes_sent "$http_referer" '
  #         '"$http_user_agent" "$http_x_forwarded_for"';

  #access_log logs/access.log main;

  sendfile    on;
  #tcp_nopush   on;

  #keepalive_timeout 0;
  keepalive_timeout 65;

  #gzip on;

  client_max_body_size 20M;

   # 关键代码块1
  proxy_temp_path ../proxy_cache/tianditu_temp;
  proxy_cache_path ../proxy_cache/tianditu levels=1:2 keys_zone=cache_one:200m inactive=1d max_size=30g;
  upstream tianditu_server {
    server t0.tianditu.com weight=1 max_fails=2 fail_timeout=30s;
    server t1.tianditu.com weight=1 max_fails=2 fail_timeout=30s;
    server t2.tianditu.com weight=1 max_fails=2 fail_timeout=30s;
    server t3.tianditu.com weight=1 max_fails=2 fail_timeout=30s;
    server t4.tianditu.com weight=1 max_fails=2 fail_timeout=30s;
    server t5.tianditu.com weight=1 max_fails=2 fail_timeout=30s;
    server t6.tianditu.com weight=1 max_fails=2 fail_timeout=30s;
  }

  server {
    listen    8088;
    server_name localhost;

    #charset koi8-r;

    #access_log logs/host.access.log main;

     # 关键代码块2
    location /DataServer {
      more_set_headers 'Access-Control-Allow-Origin: *';
      add_header Access-Control-Allow-Headers X-Requested-With;
      add_header Access-Control-Allow-Methods GET,POST,OPTIONS;

      proxy_cache cache_one;
      proxy_cache_key $uri$is_args$args;
      proxy_pass http://tianditu_server/DataServer;
    }
  }

}

下面解释一下配置文件:

关键代码块1:

1、采用nginx upstream配置一组服务地址,做负载均衡用,其效果优于openlayers顺序遍历t0至t6

2、设置了代理缓存临时地址和缓存地址,这里可以采用相对路径

关键代码块2

匹配到DataServer之后,需要

1、设置跨域header,这里用了一个新的nginx模块——headers-more,需要在编译nginx时加入,如果是windows下用nginx,可以用这个网站的安装包:https://openresty.org,它预编译了很多nginx实用模块

2、用proxy_pass将地址代理到 http://tianditu_server/DataServer地址上,其中tianditu_server就是上面配置负载均衡的服务组名称。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • 利用nginx解决cookie跨域访问的方法

    一.写在前面 最近需要把阿里云上的四台服务器的项目迁移到客户提供的新的项目中,原来的四台服务器中用到了一级域名和二级域名.比如aaa.abc.com 和bbb.abc.com 和ccc.abc.com.其中aaa.abc.com登录,通过把cookie中的信息setDomain给.abc.com.其他系统可以共享这个cookie.但是新的四台服务器中并没有申请域名,只有四个ip: 192.168.0.1    单点登录服务器 192.168.0.2 192.168.0.3 192.168.0.4

  • nginx服务器配置解决ajax的跨域问题

    在采用jquery ajax调用http请求时,发现了一系列问题: 如采用firebug调试API请求(这个API是自己服务器的应用),看到服务器明明返回200状态,response返回数据也是json格式,但ajax返回的error. 在排除json数据格式不正确的原因之后,发现了ajax error函数返回"networkerror failed to execute 'send' on 'xmlhttprequest' failed to load 'http //" XMLHt

  • Nginx解决转发地址时跨域的问题

    一.什么是跨域问题 在一个服务器A里放置了json文件,另一个服务器B想向A发送ajax请求,获取此文件,会发生错误. Chrome提示: XMLHttpRequest cannot load ******. No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'null' is therefore not allowed access. 这就是跨域问题.解决方案有不少,比较好的

  • Nginx服务器中处理AJAX跨域请求的配置方法讲解

    Nginx 实现AJAX跨域请求 AJAX从一个域请求另一个域会有跨域的问题.那么如何在nginx上实现ajax跨域请求呢?要在nginx上启用跨域请求,需要添加add_header Access-Control*指令.如下所示: location /{ add_header 'Access-Control-Allow-Origin' 'http://other.subdomain.com'; add_header 'Access-Control-Allow-Credentials' 'true

  • Nginx实现跨域使用字体文件的配置详解

    本文主要给大家介绍了关于Nginx跨域使用字体文件的相关内容,分享出来供大家参考学习,下面来一起看看详细的介绍: 问题描述 今天在使用子域名访问根域名的CSS时,发现字体无法显示,在确保CSS和Font字体的路径加载无问题后,基本确定是因为跨域的问题. 通过Nginx模块Http_Headers_Module来添加Access-Control-Allow-Origin允许的地址 console报错信息 ccess to Font at 'http://w001.static.akhack.com

  • nginx服务器通过配置来解决API的跨域问题

    前言 最近在采用jquery ajax调用http请求时,发现了一系列问题: 如采用firebug调试API请求(这个API是自己服务器的应用),看到服务器明明返回200状态,response返回数据也是json格式,但ajax返回的error. 在排除json数据格式不正确的原因之后,发现了ajax error函数返回"networkerror failed to execute 'send' on 'xmlhttprequest' failed to load 'http //"

  • 深入浅析Nginx实现AJAX跨域请求问题

    AJAX从一个域请求另一个域会有跨域的问题.那么如何在nginx上实现ajax跨域请求呢?要在nginx上启用跨域请求,需要添加add_header Access-Control*指令.如下所示: location /{ add_header 'Access-Control-Allow-Origin' 'http://other.subdomain.com'; add_header 'Access-Control-Allow-Credentials' 'true'; add_header 'Ac

  • 详解nginx代理天地图做缓存解决跨域问题

    作为一个GISer开发者,天地图是经常在项目中以底图的形式出现,其加载地址如: 1.天地图矢量:http://t{0-6}.tianditu.com/DataServer?T=vec_w&x={x}&y={y}&l={z} 2.天地图影像:http://t{0-6}.tianditu.com/DataServer?T=img_w&x={x}&y={y}&l={z} 3.天地图地形:http://t{0-6}.tianditu.com/DataServer?T

  • vue服务器代理proxyTable配置如何解决跨域

    目录 服务器代理proxyTable配置解决跨域 1.Proxy代理作用 2 .常见情况 3.应用方式 4.具体配置实例 5.配置思路 Vue.proxyTable是什么? 为什么会有proxyTable存在? 配置proxyTable 服务器代理proxyTable配置解决跨域 1.Proxy代理作用 proxy代理作用:前端服务器代理的作用是,告诉服务器任何未知请求(没有匹配到静态文件的请求),代理到一个另一个地址,从而解决跨域的问题. 2 .常见情况 前端在向后端进行资源请求的时候,后端若

  • 详解 Nginx代理功能与负载均衡

    序言 Nginx的代理功能与负载均衡功能是最常被用到的,关于nginx的基本语法常识与配置已在上篇文章中有说明,这篇就开门见山,先描述一些关于代理功能的配置,再说明负载均衡详细. Nginx代理服务的配置说明 1.上一篇中我们在http模块中有下面的配置,当代理遇到状态码为404时,我们把404页面导向百度. error_page 404 https://www.baidu.com; #错误页 然而这个配置,细心的朋友可以发现他并没有起作用. 如果我们想让他起作用,我们必须配合着下面的配置一起使

  • 详解nginx代理socket.io服务踩坑

    nginx代理了两台socket.io服务器.socket.io的工作模式是polling升级到websocket 现象 通过nginx请求服务时,出现了大量的400错误,有时候能升级到websocket,有时候会一直报错.但是直接通过 ip+端口 访问时,100%能成功. 分析 sid sid是我们这个问题的关键.在初始创建连接时(polling模式就是在模拟一个长连接),客户端会发起这样的请求: https://***/?EIO=3&transport=polling&t=154082

  • 详解nginx 代理多个服务器(多个server方式)

    上一篇文章介绍了nginx的基本配置和使用方法,并且简单的介绍了一下如何利用nginx结合tomcat进行使用,达到反向代理的作用.现在我们要使用nginx达到这样的一个目的,能够代理多个服务器. 首先修改配置文件: #user nobody; worker_processes 1; #error_log logs/error.log; #error_log logs/error.log notice; #error_log logs/error.log info; #pid logs/ngin

  • 详解Vuejs2.0 如何利用proxyTable实现跨域请求

    前言: 本地项目在请求远端服务器接口时,不可避免的会遇到跨域问题,即便是设置了Access-Control-Allow-Origin:* ,在遇到登录这些需要本地存入cookie的也会很头痛,这里笔者介绍一个在vue-cli中配置代理来解决的办法. 在~/config/dev-server.js中 使用了非常强大的http-proxy-middleware包.更多高级用法,请查阅其文档. 用法: 比如我们要请求的远端服务器为:http://192.168.400:3000 proxyTable:

  • 详解nginx惊群问题的解决方式

    对于nginx的惊群问题,我们首先需要理解的是,在nginx启动过程中,master进程会监听配置文件中指定的各个端口,然后master进程就会调用fork()方法创建各个子进程,根据进程的工作原理,子进程是会继承父进程的全部内存数据以及监听的端口的,也就是说worker进程在启动之后也是会监听各个端口的.关于惊群,指的就是当客户端有新建连接的请求到来时,就会触发各个worker进程的连接建立事件,但是只有一个worker进程能够正常处理该事件,而其他的worker进程会发现事件已经失效,从而重

  • 详解Nginx 出现 403 Forbidden 的解决办法

    Nginx 也是当前流行的一款 轻量级服务器  在日常使用中呢 也会出现一些问题  今天 学习君 在安装配置Nginx的时候就出现了 403 Forbindden 的被禁止访问的错误   网上搜索之后呢 完美解决  这里给大家分享下 话不多说 先粘 上 原版nginx 配置文件代码 worker_processes 1; events { worker_connections 1024; } http { include mime.types; default_type application/

  • 详解在Vue中如何使用axios跨域访问数据

    最近在项目中需要用到axios,所以就恶补一下这个axios到底是什么东东.越来它是vue-resource的替代品,官网也说了,以后都用axios, vue-resource不在维护.那么这个axios怎么用呢,上网搜索了一大堆,基本上都是雷同,我也不知道那些作者有没有在本地测试过.至少我按照网上的做法,总不能成功.经过几天的奋斗,我终于把它搞清楚了,为了不让其他的小伙伴们走弯路,我把我在实际操作中的例子分享给大家,希望对大家有用. 一.安装axios 老规矩,要想使用axios,我们得安装它

  • vue中axios解决跨域问题和拦截器的使用方法

    vue中axios不支持vue.use()方式声明使用. 所以有两种方法可以解决这点: 第一种: 在main.js中引入axios,然后将其设置为vue原型链上的属性,这样在组件中就可以直接 this.axios使用了 import axios from 'axios'; Vue.prototype.axios=axios; components: this.axios({ url:"a.xxx", method:'post', data:{ id:3, name:'jack' } }

随机推荐