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’:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· Vue3状态管理终极指南:Pinia保姆级教程
2020-08-23 巧妙解决Win10弹出 USB Attached SCSI(UAS)大容量存储设备 时出问题