• 前端访问geoserver服务发生跨域的解决办法,以及利用html2canvas下载绘制的地图


    我的业务场景:

    需要利用html2canvas下载Openlayers绘制的地图。

    预期:可以下载成图片甚至其他格式(svg)文件。

    结果:下载下来是个空白图片。

    排查错误:请求数据正常回显到页面上,利用html2canvas截取的时候会发生跨域,导致无法绘制。

    首先处理tomcat跨域问题

    第一步下载两个jar包:

    1. cors-filter-2.6.jar

    https://mvnrepository.com/artifact/com.thetransactioncompany/cors-filter/2.6

    2. java-property-utils-1.9.1.jar

    https://mvnrepository.com/artifact/com.thetransactioncompany/java-property-utils/1.9.1

    下载好放在 webapps/geoserver/WEB-INF/lib 文件下,如下图所示:

    第二步:修改 webapps/geoserver/WEB-INF/web.xml下的代码

    1. <?xml version="1.0" encoding="UTF-8"?>
    2. <!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
    3. <web-app>
    4. <display-name>GeoServer</display-name>
    5. <context-param>
    6. <param-name>serviceStrategy</param-name>
    7. <!-- Meaning of the different values :
    8. PARTIAL-BUFFER2
    9. - Partially buffers the first xKb to disk. Once that has buffered, the the
    10. result is streamed to the user. This will allow for most errors to be caught
    11. early.
    12. BUFFER
    13. - stores the entire response in memory first, before sending it off to
    14. the user (may run out of memory)
    15. SPEED
    16. - outputs directly to the response (and cannot recover in the case of an
    17. error)
    18. FILE
    19. - outputs to the local filesystem first, before sending it off to the user
    20. -->
    21. <param-value>PARTIAL-BUFFER2</param-value>
    22. </context-param>
    23. <context-param>
    24. <!-- see comments on the PARTIAL-BUFFER strategy -->
    25. <!-- this sets the size of the buffer. default is "50" = 50kb -->
    26. <param-name>PARTIAL_BUFFER_STRATEGY_SIZE</param-name>
    27. <param-value>50</param-value>
    28. </context-param>
    29. <!--Can be true or false (defaults to: false). -->
    30. <!--When true the JSONP (text/javascript) output format is enabled -->
    31. <!--
    32. <context-param>
    33. <param-name>ENABLE_JSONP</param-name>
    34. <param-value>true</param-value>
    35. </context-param>
    36. -->
    37. <!--
    38. <context-param>
    39. <param-name>PROXY_BASE_URL</param-name>
    40. <param-value>http://82.58.146.45/geoserver</param-value>
    41. </context-param>
    42. -->
    43. <!--
    44. <context-param>
    45. <param-name>GEOSERVER_DATA_DIR</param-name>
    46. <param-value>C:\eclipse\workspace\geoserver_trunk\cite\confCiteWFSPostGIS</param-value>
    47. </context-param>
    48. -->
    49. <!-- pick up all spring application contexts -->
    50. <context-param>
    51. <param-name>contextConfigLocation</param-name>
    52. <param-value>classpath*:/applicationContext.xml classpath*:/applicationSecurityContext.xml</param-value>
    53. </context-param>
    54. <filter>
    55. <filter-name>FlushSafeFilter</filter-name>
    56. <filter-class>org.geoserver.filters.FlushSafeFilter</filter-class>
    57. </filter>
    58. <filter>
    59. <filter-name>Set Character Encoding</filter-name>
    60. <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    61. <init-param>
    62. <param-name>encoding</param-name>
    63. <param-value>UTF-8</param-value>
    64. </init-param>
    65. </filter>
    66. <filter>
    67. <filter-name>SessionDebugger</filter-name>
    68. <filter-class>org.geoserver.filters.SessionDebugFilter</filter-class>
    69. </filter>
    70. <filter>
    71. <filter-name>filterChainProxy</filter-name>
    72. <filter-class> org.springframework.web.filter.DelegatingFilterProxy</filter-class>
    73. </filter>
    74. <filter>
    75. <filter-name>xFrameOptionsFilter</filter-name>
    76. <filter-class>org.geoserver.filters.XFrameOptionsFilter</filter-class>
    77. </filter>
    78. <filter>
    79. <filter-name>GZIP Compression Filter</filter-name>
    80. <filter-class>org.geoserver.filters.GZIPFilter</filter-class>
    81. <init-param>
    82. <!-- The compressed-types parameter is a comma-separated list of regular expressions.
    83. If a mime type matches any of the regular expressions then it will be compressed.
    84. -->
    85. <param-name>compressed-types</param-name>
    86. <param-value>text/.*,.*xml.*,application/json,application/x-javascript</param-value>
    87. </init-param>
    88. </filter>
    89. <filter>
    90. <filter-name>Advanced Dispatch Filter</filter-name>
    91. <filter-class>org.geoserver.platform.AdvancedDispatchFilter</filter-class>
    92. <!--
    93. This filter allows for a single mapping to the spring dispatcher. However using /* as a mapping
    94. in a servlet mapping causes the servlet path to be "/" of the request. This causes problems with
    95. library like wicket and restlet. So this filter fakes the servlet path by assuming the first
    96. component of the path is the mapped path.
    97. -->
    98. </filter>
    99. <filter>
    100. <filter-name>Spring Delegating Filter</filter-name>
    101. <filter-class>org.geoserver.filters.SpringDelegatingFilter</filter-class>
    102. <!--
    103. This filter allows for filters to be loaded via spring rather than
    104. registered here in web.xml. One thing to note is that for such filters
    105. init() is not called. INstead any initialization is performed via spring
    106. ioc.
    107. -->
    108. </filter>
    109. <filter>
    110. <filter-name>Thread locals cleanup filter</filter-name>
    111. <filter-class>org.geoserver.filters.ThreadLocalsCleanupFilter</filter-class>
    112. <!--
    113. This filter cleans up thread locals Geotools is setting up for concurrency and performance
    114. reasons
    115. -->
    116. </filter>
    117. <!-- Uncomment following filter to enable CORS in Jetty. Do not forget the second config block further down.
    118. <filter>
    119. <filter-name>cross-origin</filter-name>
    120. <filter-class>org.eclipse.jetty.servlets.CrossOriginFilter</filter-class>
    121. <init-param>
    122. <param-name>chainPreflight</param-name>
    123. <param-value>false</param-value>
    124. </init-param>
    125. <init-param>
    126. <param-name>allowedOrigins</param-name>
    127. <param-value>*</param-value>
    128. </init-param>
    129. <init-param>
    130. <param-name>allowedMethods</param-name>
    131. <param-value>GET,POST,PUT,DELETE,HEAD,OPTIONS</param-value>
    132. </init-param>
    133. <init-param>
    134. <param-name>allowedHeaders</param-name>
    135. <param-value>*</param-value>
    136. </init-param>
    137. </filter>
    138. -->
    139. <!-- Uncomment following filter to enable CORS in Tomcat. Do not forget the second config block further down.
    140. <filter>
    141. <filter-name>cross-origin</filter-name>
    142. <filter-class>org.apache.catalina.filters.CorsFilter</filter-class>
    143. <init-param>
    144. <param-name>cors.allowed.origins</param-name>
    145. <param-value>*</param-value>
    146. </init-param>
    147. <init-param>
    148. <param-name>cors.allowed.methods</param-name>
    149. <param-value>GET,POST,PUT,DELETE,HEAD,OPTIONS</param-value>
    150. </init-param>
    151. <init-param>
    152. <param-name>cors.allowed.headers</param-name>
    153. <param-value>*</param-value>
    154. </init-param>
    155. </filter>
    156. -->
    157. <!--
    158. THIS FILTER MAPPING MUST BE THE FIRST ONE, otherwise we end up with ruined chars in the input from the GUI
    159. See the "Note" in the Tomcat character encoding guide:
    160. http://wiki.apache.org/tomcat/FAQ/CharacterEncoding
    161. -->
    162. <filter-mapping>
    163. <filter-name>Set Character Encoding</filter-name>
    164. <url-pattern>/*</url-pattern>
    165. </filter-mapping>
    166. <!-- Uncomment following filter to enable CORS
    167. <filter-mapping>
    168. <filter-name>cross-origin</filter-name>
    169. <url-pattern>/*</url-pattern>
    170. </filter-mapping>
    171. -->
    172. <filter-mapping>
    173. <filter-name>FlushSafeFilter</filter-name>
    174. <url-pattern>/*</url-pattern>
    175. </filter-mapping>
    176. <filter-mapping>
    177. <filter-name>SessionDebugger</filter-name>
    178. <url-pattern>/*</url-pattern>
    179. </filter-mapping>
    180. <filter-mapping>
    181. <filter-name>GZIP Compression Filter</filter-name>
    182. <url-pattern>/*</url-pattern>
    183. </filter-mapping>
    184. <filter-mapping>
    185. <filter-name>xFrameOptionsFilter</filter-name>
    186. <url-pattern>/*</url-pattern>
    187. </filter-mapping>
    188. <!--
    189. If you want to use your security system comment out this one too
    190. -->
    191. <filter-mapping>
    192. <filter-name>filterChainProxy</filter-name>
    193. <url-pattern>/*</url-pattern>
    194. </filter-mapping>
    195. <filter-mapping>
    196. <filter-name>Advanced Dispatch Filter</filter-name>
    197. <url-pattern>/*</url-pattern>
    198. </filter-mapping>
    199. <filter-mapping>
    200. <filter-name>Spring Delegating Filter</filter-name>
    201. <url-pattern>/*</url-pattern>
    202. </filter-mapping>
    203. <filter-mapping>
    204. <filter-name>Thread locals cleanup filter</filter-name>
    205. <url-pattern>/*</url-pattern>
    206. </filter-mapping>
    207. <!-- general initializer, should be first thing to execute -->
    208. <listener>
    209. <listener-class>org.geoserver.GeoserverInitStartupListener</listener-class>
    210. </listener>
    211. <!-- logging initializer, should execute before spring context startup -->
    212. <listener>
    213. <listener-class>org.geoserver.logging.LoggingStartupContextListener</listener-class>
    214. </listener>
    215. <!-- spring context loader -->
    216. <listener>
    217. <listener-class>org.geoserver.platform.GeoServerContextLoaderListener</listener-class>
    218. </listener>
    219. <!-- http session listener proxy -->
    220. <listener>
    221. <listener-class>org.geoserver.platform.GeoServerHttpSessionListenerProxy</listener-class>
    222. </listener>
    223. <!-- request context listener for session-scoped beans -->
    224. <listener>
    225. <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
    226. </listener>
    227. <!-- spring dispatcher servlet, dispatches all incoming requests -->
    228. <servlet>
    229. <servlet-name>dispatcher</servlet-name>
    230. <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    231. </servlet>
    232. <!-- single mapping to spring, this only works properly if the advanced dispatch filter is
    233. active -->
    234. <servlet-mapping>
    235. <servlet-name>dispatcher</servlet-name>
    236. <url-pattern>/*</url-pattern>
    237. </servlet-mapping>
    238. <mime-mapping>
    239. <extension>xsl</extension>
    240. <mime-type>text/xml</mime-type>
    241. </mime-mapping>
    242. <mime-mapping>
    243. <extension>sld</extension>
    244. <mime-type>text/xml</mime-type>
    245. </mime-mapping>
    246. <mime-mapping>
    247. <extension>json</extension>
    248. <mime-type>application/json</mime-type>
    249. </mime-mapping>
    250. <!-- 提供跨域支持 (下面的代码是核心其他用自己的)-->
    251. <filter>
    252. <filter-name>CORS</filter-name>
    253. <filter-class>com.thetransactioncompany.cors.CORSFilter</filter-class>
    254. <init-param>
    255. <param-name>cors.allowOrigin</param-name>
    256. <param-value>*</param-value>
    257. </init-param>
    258. <init-param>
    259. <param-name>cors.supportedMethods</param-name>
    260. <param-value>GET, POST, HEAD, PUT, DELETE</param-value>
    261. </init-param>
    262. <init-param>
    263. <param-name>cors.supportedHeaders</param-name>
    264. <param-value>Accept, Origin, X-Requested-With, Content-Type, Last-Modified</param-value>
    265. </init-param>
    266. <init-param>
    267. <param-name>cors.exposedHeaders</param-name>
    268. <param-value>Set-Cookie</param-value>
    269. </init-param>
    270. <init-param>
    271. <param-name>cors.supportsCredentials</param-name>
    272. <param-value>true</param-value>
    273. </init-param>
    274. </filter>
    275. <filter-mapping>
    276. <filter-name>CORS</filter-name>
    277. <url-pattern>/*</url-pattern>
    278. </filter-mapping>
    279. <welcome-file-list>
    280. <welcome-file>index.html</welcome-file>
    281. </welcome-file-list>
    282. </web-app>

    接下来是修改前端代码:

    先下载html2canvas依赖:

    npm install --save html2canvas

    // 下载的代码
    download() {
      const el = document.getElementById("shuilunColorMap")
      html2canvas(el, {
        backgroundColor: '#07253B',
        useCORS: true,  // 允许跨域
        // foreignObjectRendering : true,
        allowTaint :false
      }).then((canvas) => {
        const dataURL = canvas.toDataURL('image/png')
        const creatDom = document.createElement('a')
        document.body.appendChild(creatDom)
        creatDom.href = dataURL
        creatDom.download = '图片'
        creatDom.click()
      })
    },
    
    // 所有的new TileLayer下面添加  crossOrigin: 'anonymous'
    var lineView = new TileLayer({
      source: new TileWMS({
        crossOrigin: 'anonymous',
        url: URL_MAP,
        params: {
          VERSION: "1.1.1",
          LAYERS: "wanjiazhai_longkou:shuilunji_dwg_Polyline",
          STYLES: "wjzLine",
        },
      }),
    });

    完成以上步骤,恭喜你又解决一个甲方的特异需求。 (欢迎妹子前来咨询,如有疑问可随时解答)

  • 相关阅读:
    在 Ubuntu 16.04 上从0到1教你如何移植osqp
    网络安全攻防对抗之隐藏通信隧道技术整理
    pytorch 1.13.0 windows GPU torch 离线安装
    torchversion.transforms的使用
    全志 d1 licheerv opensbi uboot linux debian
    ffmpeg+nginx-rtmp转发视频流
    K8s版本升级---v1.21.0至v1.21.12
    【DETR】End-to-End Object Detection with Transformers
    【学习笔记】ABC265/AGC012
    MySQL数据库管理
  • 原文地址:https://blog.csdn.net/zmx781284440/article/details/134068029