使用Velocity.js

时间:2017-09-09 13:36:14

标签: reactjs animation svg cors velocity.js

我正在构建一个界面来预览应用于SVG的动画。我试图在React中使用Velocity.js库来定位SVG的动画内部路径。我使用create-react-app

我能够将.svg文件拖放到react-dropzone输入中,该输入提供带有File对象的回调。我可以将File对象转换为base64编码的DataURL,然后我可以将其提供给<object>标记。这使SVG具有完整的扩展xml标记。

return (
    <object style={{
        width: '100%'
    }}
    id={`svg-${uuid}`} 
    type="image/svg+xml" data={dataURL}
/>)

尝试使用javascript访问SVG的contentDocument(为了直接针对动画定位gpath元素)会导致以下错误:

document.getElementById('svg-665790ae-2a36-446e-9ea9-856442e8b1dc').contentDocument

Uncaught DOMException: Failed to read the 'contentDocument' property from 'HTMLObjectElement': 
Blocked a frame with origin "http://localhost:3000" from accessing a cross-origin frame.

我正在开发本地开发环境,为localhost:3000上的React应用程序提供服务。

作为一种可能的解决方法,我将有问题的SVG上传到远程AWS S3存储桶。然后我通过远程URL检索SVG,并试图以某种方式呈现它。我尝试了以下方法:

React SVG <use> tag

<svg>
     <use xlinkHref={url}></use>
</svg>

这导致以下标记,但没有可见的SVG:

<svg>
    <use xmlns:xlink="http://www.w3.org/1999/xlink" xlink:href="https://s3.amazonaws.com/.../example.svg">
    </use>
</svg>

<object>代码

<object
    style={{
        width: '100%',
    }}
    id={`svg-${uuid}`} type="image/svg+xml" data={url}
/>

这导致以下标记,没有可见的SVG,并且导致SVG立即被浏览器下载为文件。

<object id="svg-..." type="image/svg+xml" data="https://s3.amazonaws.com/.../example.svg" style="width: 100%;"></object>

react-inlinesvg图书馆

该库发出XHR请求以检索SVG,然后将其嵌入到DOM中。

<Isvg src={url}/>

这会导致以下错误:

XMLHttpRequest cannot load https://s3.amazonaws.com/.../example.svg. 
No 'Access-Control-Allow-Origin' header is present on the requested resource. 
Origin 'http://localhost:3000' is therefore not allowed access.

SVGInjector

首先,我在SVG网址上添加了一个简单的<img>标记:

return (
    <img
        ref={node => this.testSVG = node}
        src={url} id="svg" type="image/svg+xml" />
)

这也会导致上述XMLHttpRequest错误。尝试使用节点SVGInjector(即componentDidMount)或以这种方式从ref拨打SVGInjector(this.testSVG)

const el = document.getElementById('svg');
SVGInjector(el);

导致警告消失但导致仅显示损坏的图像标记。

为了动画的目的,解决这些CORS警告或关于在React中将SVG嵌入DOM的正确方法的任何帮助都将非常感激。也许我需要做的是通过服务器下载图像,并直接从服务器文件系统(例如,从/public文件夹)暂时提供它。这不是我的首选方法,因为我已经使用AWS S3进行图像托管。

1 个答案:

答案 0 :(得分:2)

答案是在AWS S3控制台中启用CORS。见stackoverflow.com/questions/17533888/s3-access-control-allow-origin-header。默认情况下,CORS配置似乎没有启用,因此我必须保存它才能使其生效。

<!-- Sample policy -->
<CORSConfiguration>
    <CORSRule>
        <AllowedOrigin>*</AllowedOrigin>
        <AllowedMethod>GET</AllowedMethod>
        <MaxAgeSeconds>3000</MaxAgeSeconds>
        <AllowedHeader>Authorization</AllowedHeader>
    </CORSRule>
</CORSConfiguration>

感谢sideshowbarker提出此建议。正如他所提到的,如果您从另一个域中提供您无权访问的图像,则可能需要使用代理。有关详细信息,请参阅如何使用CORS代理来解决“No Access-Control-Allow-Origin标题”问题部分下的stackoverflow.com/a/43881141/441757