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就是上面配置負載均衡的服務組名稱。