一 Canvas跨域現(xiàn)象
地圖導(dǎo)出是地圖中常用的功能,并且OpenLayers3中也提供了兩個(gè)地圖導(dǎo)出的例子:
http://openlayers.org/en/latest/examples/export-map.html http://openlayers.org/en/latest/examples/export-pdf.html。
看到這兩個(gè)例子我們都很興奮,直接copy過來不就實(shí)現(xiàn)導(dǎo)出地圖了嗎?so easy,媽媽再也不用擔(dān)心我導(dǎo)出不了地圖圖片啦!
但當(dāng)我們抄好代碼執(zhí)行時(shí),現(xiàn)實(shí)就是這么赤裸裸的打臉:
我的代碼如下:
//街道圖
Layer.streetLayer=new ol.layer.Tile({
source: new ol.source.XYZ({
url: 'http://www.google.cn/maps/vt?pb=!1m5!1m4!1i{z}!2i{x}!3i{y}!4i256!2m3!1e0!2sm!3i342009817!3m9!2szh-CN!3sCN!5e18!12m1!1e47!12m3!1e37!2m1!1ssmartmaps!4e0&token=32965'
})
});
例子的圖層代碼如下:
layer=new ol.layer.Tile({ source: new ol.source.OSM() });
沒多寫一行代碼的飄逸,抄過來直接運(yùn)行,報(bào)錯(cuò)如下:

二 問題排查
檢查案例源碼發(fā)現(xiàn)和我抄襲的代碼幾乎一模一樣,唯一區(qū)別是我使用的是谷歌底圖,例子使用的是osm的source。
new ol.layer.Tile({ source: new ol.source.OSM() }),
為了一看究竟,我們查看osm的source源碼如下:

恍然大悟,原來只需要添加這 crossOrigin:'anonymous'就可以了。
于是改寫重置自己的谷歌圖層代碼如下:
//街道圖
Layer.streetLayer=new ol.layer.Tile({
source: new ol.source.XYZ({
crossOrigin: 'anonymous',
url: 'http://www.google.cn/maps/vt?pb=!1m5!1m4!1i{z}!2i{x}!3i{y}!4i256!2m3!1e0!2sm!3i342009817!3m9!2szh-CN!3sCN!5e18!12m1!1e47!12m3!1e37!2m1!1ssmartmaps!4e0&token=32965'
})
});
這下打印正常了。
三 加載自己的wms底圖還是跨域錯(cuò)誤
我們上面通過對(duì)谷歌地圖加crossOrigin: 'anonymous'實(shí)現(xiàn)了地圖輸出了,解決canvas跨域問題了,但一般我們地圖是底圖+業(yè)務(wù)底圖(如wms)的,這時(shí)候打印發(fā)現(xiàn)還是報(bào)錯(cuò)。
Layer.streetLayer=new ol.layer.Tile({
source: new ol.source.XYZ({
crossOrigin: 'anonymous',
url: 'http://www.google.cn/maps/vt?pb=!1m5!1m4!1i{z}!2i{x}!3i{y}!4i256!2m3!1e0!2sm!3i342009817!3m9!2szh-CN!3sCN!5e18!12m1!1e47!12m3!1e37!2m1!1ssmartmaps!4e0&token=32965'
})
});
Layer.wmsship = new ol.layer.Tile({
source: new ol.source.TileWMS({
url: geoserverhost+'/gwc/service/wms',
params: {'FORMAT': 'image/png',
'VERSION': '1.1.1',
tiled: true,
STYLES: '',
LAYERS: 'ships:ta_pos_latest'
}
})
});
這個(gè)例子我們使用了谷歌底圖疊加自己的wms/gwc等瓦片圖,發(fā)現(xiàn)export還是報(bào)跨域錯(cuò)誤,理所當(dāng)讓的,我給Layer.wmsship設(shè)置crossOrigin: 'anonymous',以為就可以了,但不幸的是仍然報(bào)跨域錯(cuò)誤,一點(diǎn)沒反應(yīng)。
四 設(shè)置服務(wù)器cors徹底解決
我們發(fā)現(xiàn),谷歌,osm設(shè)置crossOrigin就可以,我們自己wms設(shè)置的crossOrigin還是不行。問題出在哪里咧?查閱資料可知,osm,google的服務(wù)器一定設(shè)置了cors,所以客戶端設(shè)置crossOrigin才會(huì)起作用,而我們自己的wms或者瓦片所在的服務(wù)器沒有設(shè)置cors,所以客戶端設(shè)置或者不設(shè)置crossOrigin,都是無效的。也就是說,只有自己的服務(wù)器設(shè)置了cors,crossOrigin才會(huì)起到作用。
我們地圖是geoserver發(fā)布的wms或者gwc,對(duì)geoserver設(shè)置cors,參考之前的博客:http://blog.csdn.net/freeland1/article/details/41204485 ,根據(jù)第三節(jié)的cors設(shè)置下自己的服務(wù)器。
服務(wù)器設(shè)置完畢后,代碼改為如下
Layer.streetLayer=new ol.layer.Tile({
visible: true,
source: new ol.source.XYZ({
crossOrigin: 'anonymous',
url: 'http://www.google.cn/maps/vt?pb=!1m5!1m4!1i{z}!2i{x}!3i{y}!4i256!2m3!1e0!2sm!3i342009817!3m9!2szh-CN!3sCN!5e18!12m1!1e47!12m3!1e37!2m1!1ssmartmaps!4e0&token=32965'
})
});
Layer.wmsship = new ol.layer.Tile({
source: new ol.source.TileWMS({
crossOrigin: 'anonymous',
url: geoserverhost+'/gwc/service/wms',
params: {'FORMAT': 'image/png',
'VERSION': '1.1.1',
tiled: true,
STYLES: '',
LAYERS: 'ships:ta_pos_latest'
}
})
});
地圖輸出終于不報(bào)錯(cuò)了,perfect!