ArcGIS API for JavaScript FeatureLayer definitionExpression 被认定为sql注入攻击

背景

   目前有一个区的图斑数据需要分乡镇展示,所以采用FeatureLayer 的 definitionExpression 构造SQL语句进行过滤,官方提供的示例

  

1 // Set definition expression in constructor to only display trees with scientific name Ulmus pumila
2 const layer = new FeatureLayer({
3   url: "https://services.arcgis.com/V6ZHFr6zdgNZuVG0/arcgis/rest/services/Landscape_Trees/FeatureServer/0",
4   definitionExpression: "Sci_Name = 'Ulmus pumila'"
5 });

     

 // Set the definition expression directly on layer instance to only display trees taller than 50ft
 layer.definitionExpression = "HEIGHT > 50";

 

 

  这个问题出来后,直接让我懵逼了,总不能把十几个乡镇的图斑分别发布出来然后加载吧,这样子太麻烦了,当然这是最坏的打算。

  “领导”的意思是让后端来封装一层,这个在其他纯前端项目还好,sql语句放到后端,返回个json就好了。但这毕竟是GIS项目,人家都封装好了,就需要个url,塞个json不合适吧....还说arcgis server发布的就只能做demo,搞得我有点怀疑人生了

环境

   Vue3.0

  @arcgis/core

问题

   利用definitionExpression 虽然方便,但是处于安全考虑,在正式环境下会被拦截。现场给的回复是“URL(0141)::where=town%20%3D%20%27320509101000%27%20and%20xcdcqk%20%3C%3E%20%270%27”,被认定为sql注入攻击 拦截了

解决方案

  其实这个只需要前端规避下在请求url里面不要携带‘where’即可,所以就不要想着直接在定义featurelayer时过滤了,这样子肯定还是会携带‘where’,所以考虑在featurelayer加载后再处理。

  我的解决方案是利用layerview的filter来做筛选:

  

 1 // display rain gauges where their water percent is over 30%
 2 // and if the gauges are completely contained by the 10-mile
 3 // buffer around the filter geometry
 4 featureLayerView.filter = new FeatureFilter({
 5   where: "percentile >= 30",
 6   geometry: filterPolygon,
 7   spatialRelationship: "contains",
 8   distance: 10,
 9   units: "miles"
10 });

 

对比

原实际项目代码:

  

 1  let definitionExpression
 2     if (townCode) {
 3       definitionExpression = `town = '${townCode}' and xcdcqk <> '0'`
 4     } else {
 5       definitionExpression = "xcdcqk <> '0'"
 6     }
 7 
 8     const patchesLayer = new FeatureLayer({
 9       id: 'patchesLayer',
10       title: '图斑',
11       url: patchesLayerUrl,
12       definitionExpression: definitionExpression, //直接在实例化FeatureLayer时设置
13       outFields: [
14         'objectid_1',
15         'fwbh',
16         'lon',
17         'lat',
18         'needCheck',
19         'fwlb',
20         'fwmj',
21         'flloors',
22         'height'
23       ],
24       objectIdField: 'objectid_1',
25       editingEnabled: true,
26       renderer: pathchRender
27     })
28     map.layers.add(patchesLayer)

 

  请求效果图,能看到查询的url里面携带‘where’:

  

  改良后的项目代码:

 1     let definitionExpression
 2     if (townCode) {
 3       definitionExpression = `town = '${townCode}' and xcdcqk <> '0'`
 4     } else {
 5       definitionExpression = "xcdcqk <> '0'"
 6     }
 7 
 8     const patchesLayer = new FeatureLayer({
 9       id: 'patchesLayer',
10       title: '图斑',
11       url: patchesLayerUrl,
12       // definitionExpression: definitionExpression,
13       outFields: [
14         'objectid_1',
15         'fwbh',
16         'lon',
17         'lat',
18         'needCheck',
19         'fwlb',
20         'fwmj',
21         'flloors',
22         'height'
23       ],
24       objectIdField: 'objectid_1',
25       editingEnabled: true,
26       renderer: pathchRender
27     })
28     map.layers.add(patchesLayer)
29     view.whenLayerView(patchesLayer).then((layerView) => {
30       patchLayerView = layerView
31     //用layerView过滤
32       patchLayerView.filter = {
33         where: definitionExpression
34       }
35     })

 

请求效果图,可以看到请求的url中已经不再携带‘where’:

  

 

 


 

  

 

 

 

 

 

 


 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章