下达需求为,后端返回的svg需要前拼接hostname+port后面拼上token,且需要通过Arcgis生成对应的svg图标点或用svg填充面,并可修改颜色,也是弄了好久才搞定,说说问题吧,现阶段能将svg嵌入的标签有三个,object,iframe和embed,常用iframe的比较多,后来遇到很多问题,三个都试了,最后还是用的iframe,因为问题不在标签,先上代码
{
this.props.svgIcons.map((item, index) => {
return (
<iframe key={index} src={item.svg} id={`svg${index}`} />
)
})
}
svgIcons是已拼接好的svg数据数组,但是因为需要可设置svg颜色,所以不能设定好填充颜色,所以呈现的是黑色即rgb(0,0,0),但是模块底色为黑色,所以需要将可选svg图标换成灰色,第一个问题来了,怎么改填充颜色,元素点进去一看,跟img src一样,那加fill就不可能实现,所以就要借助getSvgDocument拿到svg path部分,然后改了颜色再放到需要显示模块里
setSvgList = ()=>{
let svgItem=''
let svgStyle=''
for (let i=0;i<this.props.svgIcons.length;i++){
svgItem = document.getElementById(`svg${i}`).getSVGDocument()
svgStyle = svgItem.getElementsByTagName("svg")
if(svgStyle[0]){
svgStyle[0].style.fill = '#9f9f9f'
}
let svgBase64 = "data:image/svg+xml;base64," + window.btoa((new
XMLSerializer()).serializeToString(svgItem))
this.svgList.push({src:svgBase64})
this.setState({})
}
}
整体思路就是获取到svg节点,更改填充颜色,再转换格式,将转换好的svg挂载到页面上去,但是此时会有getSvgDocument()为null的问题,可以尝试先getElementById赋值并确定不为null后再getSvgDocument(),更大的问题在于元素能看到svg节点,但是会报getElementByTagName('svg‘)失败,打开网络会发现,所有的svg图标状态为被屏蔽,控制台报错,x-frame-option为 deny,不允许iframe嵌套,引入概念,X-Frame-Options HTTP响应头是用来给浏览器指示允许一个页面可否在<frame>,<iframe>,<embed>
或者<object>
中展现的标记。站点可以通过确保网站没有被嵌入到别人的站点里面,从而避免 clickjacking 攻击。但是项目需要这个模块,所以,找了很多办法,开发环境下,chrome方法为安装插件,插件名称为Ignore X-Frame headers 1.1.2; 部署测试阶段,根据不同的环境给我了不同的解决方法,nginx是在nginx.conf
,配置文件中http配置代码块里某一行添加如下语句,add_header X-Frame-Options SAMEORIGIN;,这样就可以正常获取到所需svg并进行改色操作了,如果nginx部分未生效,如未前后端分离,就找后端大哥加入这个语句吧,如果有更好的办法,可以相互交流,谢谢!