Javascript 在React组件中将SVG字符串转换为图像

Javascript 在React组件中将SVG字符串转换为图像,javascript,reactjs,svg,xss,Javascript,Reactjs,Svg,Xss,我在React组件中有一个动态生成的SVG字符串。我想将其作为图像嵌入组件中。目前,我正在使用以下内容: class SomeComponent extends React.Component { render() { var image = '<svg xmlns="http://www.w3.org/2000/svg" version="1.2" baseProfile="tiny" width="47.4" height="40.65" viewBox="21

我在React组件中有一个动态生成的SVG字符串。我想将其作为图像嵌入组件中。目前,我正在使用以下内容:

class SomeComponent extends React.Component {
    render() {
        var image = '<svg xmlns="http://www.w3.org/2000/svg" version="1.2" baseProfile="tiny" width="47.4" height="40.65" viewBox="21 18.5 158 135.5"><path d="M25,50 l150,0 0,100 -150,0 z" stroke-width="4" stroke="black" fill="rgb(128,224,255)" fill-opacity="1" ></path><path d="M25,50 L175,150 M25,150 L175,50" stroke-width="4" stroke="black" fill="black" ></path><g transform="translate(0,0)" stroke-width="4" stroke="black" fill="none" ><circle cx="100" cy="30" r="7.5" fill="black" ></circle><circle cx="70" cy="30" r="7.5" fill="black" ></circle><circle cx="130" cy="30" r="7.5" fill="black" ></circle></g></svg>';
        return (
            <div dangerouslySetInnerHTML={{ __html: image }} />
        )
    }
}
类SomeComponent扩展React.Component{
render(){
var图像=“”;
返回(
)
}
}

然而,使用一个名为
危险的setinerhtml
的属性让我非常不安。有没有一种更普遍接受(更安全)的方法来实现这一点?

我会将svg图像存储在一个单独的文件夹(
assets
)中,然后将图像导入react组件

大概是这样的:

const image = '<svg xmlns="http://www.w3.org/2000/svg" version="1.2" baseProfile="tiny" width="47.4" height="40.65" viewBox="21 18.5 158 135.5"><path d="M25,50 l150,0 0,100 -150,0 z" stroke-width="4" stroke="black" fill="rgb(128,224,255)" fill-opacity="1" ></path><path d="M25,50 L175,150 M25,150 L175,50" stroke-width="4" stroke="black" fill="black" ></path><g transform="translate(0,0)" stroke-width="4" stroke="black" fill="none" ><circle cx="100" cy="30" r="7.5" fill="black" ></circle><circle cx="70" cy="30" r="7.5" fill="black" ></circle><circle cx="130" cy="30" r="7.5" fill="black" ></circle></g></svg>';
const buff = new Buffer(image);
const base64data = buff.toString('base64');

return <img src='data:image/svg+xml;base64,${base64data }' alt="" />
SomeComponent.js:

import { SampleImage } from '../assets/SomeFile';

class SomeComponent extends React.Component {
    render() {

        return (
            <div>
              <img src={SampleImage} />
            <div/>
        )
    }
}
从“../assets/SomeFile”导入{SampleImage};
类SomeComponent扩展了React.Component{
render(){
返回(
)
}
}
SomeFile.svg:

<?xmlns="http://www.w3.org/2000/svg" version="1.2"encoding="UTF-8"?>

 <svg baseProfile="tiny" width="47.4" height="40.65" viewBox="21 18.5 158 135.5"><path d="M25,50 l150,0 0,100 -150,0 z" stroke-width="4" stroke="black" fill="rgb(128,224,255)" fill-opacity="1" ></path><path d="M25,50 L175,150 M25,150 L175,50" stroke-width="4" stroke="black" fill="black" ></path><g transform="translate(0,0)" stroke-width="4" stroke="black" fill="none" ><circle cx="100" cy="30" r="7.5" fill="black" ></circle><circle cx="70" cy="30" r="7.5" fill="black" ></circle><circle cx="130" cy="30" r="7.5" fill="black" >
    </circle></g>
 </svg>

由于SVG是动态生成的,您不能将其存储为资产,作为
危险的HTML
的替代方案,您只需将其设置为图像上的
数据URI
。所以有点像


class SomeComponent extends React.Component {
    render() {
        const image = '<svg xmlns="http://www.w3.org/2000/svg" version="1.2" baseProfile="tiny" width="47.4" height="40.65" viewBox="21 18.5 158 135.5"><path d="M25,50 l150,0 0,100 -150,0 z" stroke-width="4" stroke="black" fill="rgb(128,224,255)" fill-opacity="1" ></path><path d="M25,50 L175,150 M25,150 L175,50" stroke-width="4" stroke="black" fill="black" ></path><g transform="translate(0,0)" stroke-width="4" stroke="black" fill="none" ><circle cx="100" cy="30" r="7.5" fill="black" ></circle><circle cx="70" cy="30" r="7.5" fill="black" ></circle><circle cx="130" cy="30" r="7.5" fill="black" ></circle></g></svg>';
        return (
            <div>
              <img src={`data:image/svg+xml;utf8,${image}` />
            </div>
        )
    }
}


类SomeComponent扩展了React.Component{
render(){
常量图像=“”;
返回(
)
}
}

请参见此处的帖子:

您可以做的一件事是将svg字符串转换为base64,然后像这样使用它:

const image = '<svg xmlns="http://www.w3.org/2000/svg" version="1.2" baseProfile="tiny" width="47.4" height="40.65" viewBox="21 18.5 158 135.5"><path d="M25,50 l150,0 0,100 -150,0 z" stroke-width="4" stroke="black" fill="rgb(128,224,255)" fill-opacity="1" ></path><path d="M25,50 L175,150 M25,150 L175,50" stroke-width="4" stroke="black" fill="black" ></path><g transform="translate(0,0)" stroke-width="4" stroke="black" fill="none" ><circle cx="100" cy="30" r="7.5" fill="black" ></circle><circle cx="70" cy="30" r="7.5" fill="black" ></circle><circle cx="130" cy="30" r="7.5" fill="black" ></circle></g></svg>';
const buff = new Buffer(image);
const base64data = buff.toString('base64');

return <img src='data:image/svg+xml;base64,${base64data }' alt="" />
只需使用此软件包:

例如:

import SVG from 'react-inlinesvg';

...    

const mySVG = '<svg xmlns="http://www.w3.org/2000/svg">...</svg>';
return <SVG src={mySVG} />;
从'react inlinesvg'导入SVG;
...    
常量mySVG='…';
返回;
React ref
innerHTML
配合使用效果非常好,而且非常干净。
var image='';
const useApp=()=>{
const svgWrapperRef=React.useRef();
React.useffect(()=>{
svgWrapperRef.current.innerHTML=图像;
}, [])
返回{
svgWrapperRef
}
}
常量应用=()=>{
const{svgWrapperRef}=useApp()
返回(
)
}
const root=document.getElementById('root'))
ReactDOM.render(,root)


这里有一个类似问题的好答案:这是与SVG合作的正常方式。我有一个字符串,想从中生成一个元素。字符串来自服务器如果您最终使用此方法,则可能需要将SVG输出包装在encodeURIComponent()中: