怎么用nginx代理天地圖做緩存解決跨域問題

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有兩個取值

怎么用nginx代理天地圖做緩存解決跨域問題

在開發過程中,往往需要本地運行開發版,服務器運行生產版。當兩個版本在同一個瀏覽器中訪問時,設置了crossorigin就會出現跨域問題,如下圖所示的錯誤,

has been blocked by cors policy: no ‘access-control-allow-origin’header is present on the requested resource.

怎么用nginx代理天地圖做緩存解決跨域問題

注:只有天地圖設置了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就是上面配置負載均衡的服務組名稱。

? 版權聲明
THE END
喜歡就支持一下吧
點贊10 分享