对于那些使用 Rails 的人,当谈到 @Forivin 提出的第四个问题时,我就是这样做的。
问题是当 Toast 调用存储在 S3 上的图像时,我会在 Chrome 上收到 CORS 错误,但 firefox 很好。有很多关于这方面的文章,基本上我发现最好的方法是在我的代码中使用代理。我仍然可以让我的 CORS 源指向我的主机,并且由于呼叫是通过代理从我的主机发出的,所以 S3 和 Chrome 很高兴。我的 S3 CORS 配置如下所示(允许子域):
<?xml version="1.0" encoding="UTF-8"?>
<CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
<CORSRule>
<AllowedOrigin>http://*.mycompany.com</AllowedOrigin>
<AllowedMethod>POST</AllowedMethod>
<AllowedMethod>GET</AllowedMethod>
<AllowedMethod>PUT</AllowedMethod>
<AllowedMethod>DELETE</AllowedMethod>
<AllowedMethod>HEAD</AllowedMethod>
<AllowedHeader>*</AllowedHeader>
</CORSRule>
</CORSConfiguration>
在您的 Rails 项目中执行以下操作:
将 rack-proxy gem 添加到你的Gemfile
gem 'rack-proxy'
创建代理文件。s3 路径经过 URI 编码并附加到路由的末尾。该路由仅用于代理,因此它可以是任何东西,因为它将被重新路由到 s3。
app/proxy/s3_proxy.rb
class S3Proxy < Rack::Proxy
def perform_request(env)
if env['REQUEST_PATH'] =~ %r{^/my/dummy/path}
s3_path = CGI.unescape(env['REQUEST_PATH'][15..-1])
uri = URI.parse(s3_path)
env['HTTP_HOST'] = uri.host
env['SERVER_PORT'] = uri.port
env['REQUEST_PATH'] = s3_path
env['REQUEST_URI'] = s3_path
env['PATH_INFO'] = s3_path
env['rack.url_scheme'] = 'https'
super(env)
else
@app.call(env)
end
end
end
添加到application.rb
文件:
require "./app/proxy/s3_proxy"
class Application < Rails::Application
...
config.middleware.use S3Proxy
end
routes.rb
get "/my/dummy/path/:s3_url", to: "my_controller#dummy_path"
中的控制器方法my_controller.rb
。在这里渲染什么都没关系,因为它将被代理重定向。我们可能没有办法逃脱,因为代理无论如何都会改变。
def dummy_path
render plain: ""
end
最后在我的 Vue 代码中,我调用 Toast 编辑器,首先填充一个空白图像。然后在安装组件时,我加载 s3 图像并覆盖现有图像并调整画布大小。我发现在读取 s3 图像之前安装它需要稍微延迟。s3 图像是我在 props 中传递的预签名 url。
<template lang="pug">
.v-image-editor-tool
tui-image-editor(:include-ui='useDefaultUI' :options="editorOptions" ref="tuiImageEditor")
</template>
<script lang="coffee">
import { ImageEditor } from '@toast-ui/vue-image-editor'
import 'tui-image-editor/dist/tui-image-editor.min.css'
export default app =
props: ['imageUrl']
data: ->
useDefaultUI: true
editorOptions:
cssMaxWidth: 700
cssMaxHeight: 700
usageStatistics: false
includeUI:
loadImage:
path: 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7'
name: 'Blank'
menuBarPosition: 'bottom'
mounted: ->
fn = => this.$refs.tuiImageEditor.invoke('loadImageFromURL', @imageUrl, 'Image').then (result) =>
this.$refs.tuiImageEditor.invoke('ui.resizeEditor', { imageSize: { newWidth: result.newWidth, newHeight: result.newHeight }})
setTimeout(fn, 600)
components:
'tui-image-editor': ImageEditor
</script>