ROR Cropper JS 在本地工作但不在 heroku 上工作
ROR Cropper JS working in local but not on heroku
我正在使用 ROR、stymulus、cropperjs 和活动目录直接上传。我的项目图片在 amazon s3 上
我想允许用户在表单中上传图片,以便在上传之前在表单中裁剪它们。
我跟着this tutorial漂移
在用户完成表单之前应该使用直接上传来上传图片,这样可以显示预览和裁剪。
我遇到的问题是它只能在本地工作,不能在生产中的 heroku 上工作。
这是我的表格:
<div class="field" data-controller='instant-upload cropper'
data-cropper-model-value='workshop'>
<label class="btn-cta" style="display:flex; margin-bottom: 20px; max-width: 40%;
margin-left: 0px">
Photo principale
<span style="display:none;">
<%= form.file_field :main_picture, 'data-instant-upload-target': 'input2',
'data-action': 'instant-upload#changed', :class => 'btn-cta', onchange: "validateFiles(this);",
data: { max_file_size: 5.megabytes }%>
</span>
</label>
<%= image_tag @workshop.main_picture.variant(resize_to_limit: [200, 200]),
width: 200, height: 200,
'data-instant-upload-target': 'image',
'data-cropper-target': 'image',
'data-action': 'instant-uploaded->cropper#changed' if @workshop.main_picture.attached? %>
<div style="margin-bottom: 30px">
<%= content_tag :img, nil, src: nil, width: 200, height: 200,
'data-instant-upload-target': 'image',
'data-cropper-target': 'image',
'data-action': 'instant-uploaded->cropper#changed' unless @workshop.main_picture.attached? %>
</div>
</div>
这是我的 cropper_controller.js:
import { Controller } from "stimulus"
import Cropper from "cropperjs"
import "cropperjs/dist/cropper.css"
export default class extends Controller {
static targets = ["image"]
static values = { model: String }
changed() {
let _this = this
new Cropper(this.imageTarget, {
crop(event) {
_this.crop_x().value = event.detail.x
_this.crop_y().value = event.detail.y
_this.crop_width().value = event.detail.width
_this.crop_height().value = event.detail.height
console.log("x"+ event.detail.x);
console.log("y"+ event.detail.y);
console.log("width"+ event.detail.width);
console.log("height"+ event.detail.height);
}
})
}
crop_x() {
if (this._crop_x == undefined) {
this._crop_x = document.createElement("input")
this._crop_x.name = `${this.modelValue}[crop_x]`
this._crop_x.type = "hidden"
this.imageTarget.parentNode.insertBefore(this._crop_x, this.imageTarget.nextSibling)
}
return this._crop_x
}
crop_y() {
if (this._crop_y == undefined) {
this._crop_y = document.createElement("input")
this._crop_y.name = `${this.modelValue}[crop_y]`
this._crop_y.type = "hidden"
this.imageTarget.parentNode.insertBefore(this._crop_y, this.imageTarget.nextSibling)
}
return this._crop_y
}
crop_width() {
if (this._crop_width == undefined) {
this._crop_width = document.createElement("input")
this._crop_width.name = `${this.modelValue}[crop_width]`
this._crop_width.type = "hidden"
this.imageTarget.parentNode.insertBefore(this._crop_width, this.imageTarget.nextSibling)
}
return this._crop_width
}
crop_height() {
if (this._crop_height == undefined) {
this._crop_height = document.createElement("input")
this._crop_height.name = `${this.modelValue}[crop_height]`
this._crop_height.type = "hidden"
this.imageTarget.parentNode.insertBefore(this._crop_height, this.imageTarget.nextSibling)
}
return this._crop_height
}
}
这是我的 instant_upload_controller.js:
import { Controller } from "stimulus"
import { DirectUpload } from "@rails/activestorage"
export default class extends Controller {
static targets = ["input2", "image"]
event() {
if (this._event == undefined) {
this._event = document.createEvent("CustomEvent")
this._event.initCustomEvent("instant-uploaded", true, true, null)
}
return this._event
}
changed() {
Array.from(this.input2Target.files).forEach(file => {
const upload = new DirectUpload(file, this.postURL())
upload.create((error, blob) => {
this.hiddenInput().value = blob.signed_id
// this.input2Target.type = "hidden"
this.imageTarget.src = `${this.getURL()}/${blob.signed_id}/${blob.filename}`
this.imageTarget.dispatchEvent(this.event())
console.log("changed passe")
})
})
}
hiddenInput() {
if (this._hiddenInput2 == undefined ) {
this._hiddenInput2 = document.createElement('input2')
this._hiddenInput2.name = this.input2Target.name
this._hiddenInput2.type = "hidden"
this.input2Target.parentNode.insertBefore(this._hiddenInput2, this.input2Target.nextSibling)
console.log("hiddenInput passe")
}
return this._hiddenInput2
}
postURL() {
console.log("posturl est appelé")
return '/rails/active_storage/direct_uploads'
}
getURL() {
console.log("geturl est appelé")
return '/rails/active_storage/blobs'
}
}
这就是我在 amazon s3 控制台中定义 CORS 的方式
[ { "AllowedHeaders": [ "Origin", "Content-Type", "Content-MD5", "Content-Disposition" ], "AllowedMethods": [ "PUT", "GET" ], "AllowedOrigins": [ "https://site-name.herokuapp.com" ], "ExposeHeaders": [ "Origin", "Content-Type", "Content-MD5", "Content-Disposition" ], }]
我检查了控制台,我将控制台登录到我所有的 js 中,一切正常。
我在浏览器开发工具中检查了网络,本地和产品中的一切看起来都很相似,我没有错误。
当我尝试上传图片时,图片预览正常,只是剪裁 windows 打不开,我上传的图片放大了两倍。
这让我觉得在amazon s3 上直接上传效果很好。它看起来像是在 heroku 上不能正常工作的 cropper 模块。 cropper js文件在heroku上,在firefox中使用dev tool的debug模式可以看到。
也许 heroku 没有安装或初始化好 cropper.js。
我没有看到任何错误消息
我在这个问题上被屏蔽了两天,如果你对我可以检查的东西有任何想法,我可以阅读的东西,我可以尝试的东西......或者如果你通过了这个问题,请不要犹豫回答.
哎,折腾了几天,终于在漂移ruby网站上找到了解决方法。
它在 heroku 上不起作用,因为我们必须在 webpack 中导入 css。我必须在布局中添加以下行
<%= stylesheet_pack_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
我正在使用 ROR、stymulus、cropperjs 和活动目录直接上传。我的项目图片在 amazon s3 上 我想允许用户在表单中上传图片,以便在上传之前在表单中裁剪它们。
我跟着this tutorial漂移
在用户完成表单之前应该使用直接上传来上传图片,这样可以显示预览和裁剪。
我遇到的问题是它只能在本地工作,不能在生产中的 heroku 上工作。
这是我的表格:
<div class="field" data-controller='instant-upload cropper'
data-cropper-model-value='workshop'>
<label class="btn-cta" style="display:flex; margin-bottom: 20px; max-width: 40%;
margin-left: 0px">
Photo principale
<span style="display:none;">
<%= form.file_field :main_picture, 'data-instant-upload-target': 'input2',
'data-action': 'instant-upload#changed', :class => 'btn-cta', onchange: "validateFiles(this);",
data: { max_file_size: 5.megabytes }%>
</span>
</label>
<%= image_tag @workshop.main_picture.variant(resize_to_limit: [200, 200]),
width: 200, height: 200,
'data-instant-upload-target': 'image',
'data-cropper-target': 'image',
'data-action': 'instant-uploaded->cropper#changed' if @workshop.main_picture.attached? %>
<div style="margin-bottom: 30px">
<%= content_tag :img, nil, src: nil, width: 200, height: 200,
'data-instant-upload-target': 'image',
'data-cropper-target': 'image',
'data-action': 'instant-uploaded->cropper#changed' unless @workshop.main_picture.attached? %>
</div>
</div>
这是我的 cropper_controller.js:
import { Controller } from "stimulus"
import Cropper from "cropperjs"
import "cropperjs/dist/cropper.css"
export default class extends Controller {
static targets = ["image"]
static values = { model: String }
changed() {
let _this = this
new Cropper(this.imageTarget, {
crop(event) {
_this.crop_x().value = event.detail.x
_this.crop_y().value = event.detail.y
_this.crop_width().value = event.detail.width
_this.crop_height().value = event.detail.height
console.log("x"+ event.detail.x);
console.log("y"+ event.detail.y);
console.log("width"+ event.detail.width);
console.log("height"+ event.detail.height);
}
})
}
crop_x() {
if (this._crop_x == undefined) {
this._crop_x = document.createElement("input")
this._crop_x.name = `${this.modelValue}[crop_x]`
this._crop_x.type = "hidden"
this.imageTarget.parentNode.insertBefore(this._crop_x, this.imageTarget.nextSibling)
}
return this._crop_x
}
crop_y() {
if (this._crop_y == undefined) {
this._crop_y = document.createElement("input")
this._crop_y.name = `${this.modelValue}[crop_y]`
this._crop_y.type = "hidden"
this.imageTarget.parentNode.insertBefore(this._crop_y, this.imageTarget.nextSibling)
}
return this._crop_y
}
crop_width() {
if (this._crop_width == undefined) {
this._crop_width = document.createElement("input")
this._crop_width.name = `${this.modelValue}[crop_width]`
this._crop_width.type = "hidden"
this.imageTarget.parentNode.insertBefore(this._crop_width, this.imageTarget.nextSibling)
}
return this._crop_width
}
crop_height() {
if (this._crop_height == undefined) {
this._crop_height = document.createElement("input")
this._crop_height.name = `${this.modelValue}[crop_height]`
this._crop_height.type = "hidden"
this.imageTarget.parentNode.insertBefore(this._crop_height, this.imageTarget.nextSibling)
}
return this._crop_height
}
}
这是我的 instant_upload_controller.js:
import { Controller } from "stimulus"
import { DirectUpload } from "@rails/activestorage"
export default class extends Controller {
static targets = ["input2", "image"]
event() {
if (this._event == undefined) {
this._event = document.createEvent("CustomEvent")
this._event.initCustomEvent("instant-uploaded", true, true, null)
}
return this._event
}
changed() {
Array.from(this.input2Target.files).forEach(file => {
const upload = new DirectUpload(file, this.postURL())
upload.create((error, blob) => {
this.hiddenInput().value = blob.signed_id
// this.input2Target.type = "hidden"
this.imageTarget.src = `${this.getURL()}/${blob.signed_id}/${blob.filename}`
this.imageTarget.dispatchEvent(this.event())
console.log("changed passe")
})
})
}
hiddenInput() {
if (this._hiddenInput2 == undefined ) {
this._hiddenInput2 = document.createElement('input2')
this._hiddenInput2.name = this.input2Target.name
this._hiddenInput2.type = "hidden"
this.input2Target.parentNode.insertBefore(this._hiddenInput2, this.input2Target.nextSibling)
console.log("hiddenInput passe")
}
return this._hiddenInput2
}
postURL() {
console.log("posturl est appelé")
return '/rails/active_storage/direct_uploads'
}
getURL() {
console.log("geturl est appelé")
return '/rails/active_storage/blobs'
}
}
这就是我在 amazon s3 控制台中定义 CORS 的方式
[ { "AllowedHeaders": [ "Origin", "Content-Type", "Content-MD5", "Content-Disposition" ], "AllowedMethods": [ "PUT", "GET" ], "AllowedOrigins": [ "https://site-name.herokuapp.com" ], "ExposeHeaders": [ "Origin", "Content-Type", "Content-MD5", "Content-Disposition" ], }]
我检查了控制台,我将控制台登录到我所有的 js 中,一切正常。
我在浏览器开发工具中检查了网络,本地和产品中的一切看起来都很相似,我没有错误。
当我尝试上传图片时,图片预览正常,只是剪裁 windows 打不开,我上传的图片放大了两倍。
这让我觉得在amazon s3 上直接上传效果很好。它看起来像是在 heroku 上不能正常工作的 cropper 模块。 cropper js文件在heroku上,在firefox中使用dev tool的debug模式可以看到。
也许 heroku 没有安装或初始化好 cropper.js。
我没有看到任何错误消息
我在这个问题上被屏蔽了两天,如果你对我可以检查的东西有任何想法,我可以阅读的东西,我可以尝试的东西......或者如果你通过了这个问题,请不要犹豫回答.
哎,折腾了几天,终于在漂移ruby网站上找到了解决方法。
它在 heroku 上不起作用,因为我们必须在 webpack 中导入 css。我必须在布局中添加以下行
<%= stylesheet_pack_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>