ROR Cropper JS 在本地工作,但不在 heroku

Posted

技术标签:

【中文标题】ROR Cropper JS 在本地工作,但不在 heroku【英文标题】:ROR Cropper JS working in local but not on heroku 【发布时间】:2021-11-16 09:51:00 【问题描述】:

我正在使用 ROR、stymulus、cropperjs 和 Active Directory 直接上传。我的项目图片在 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 中,一切看起来都正常。

我在浏览器开发工具中检查了网络,本地和产品中的一切看起来都相似,我没有错误。

当我尝试上传图片时,图片的预览工作正常,只是裁剪窗口没有打开,我上传的图片大了两倍。

这让我觉得亚马逊 s3 上的直接上传效果很好。它看起来像是在heroku上不能很好地工作的cropper模块。 cropper js文件在heroku上,在firefox中使用dev工具的debug模式可以看到。

也许 heroku 没有安装或初始化好cropper.js。

我没有看到任何错误信息

我在这个问题上被阻止了两天,如果你对我可以检查的事情、我可以阅读的事情、我可以尝试的事情有任何想法......或者如果你通过了这个问题,请不要犹豫回答。

【问题讨论】:

【参考方案1】:

哎,折腾了几天,终于在drifting ruby​​ 网站上找到了解决办法。

它在 heroku 上不起作用,因为我们必须在 webpack 中导入 css。我必须在布局中添加以下行

<%= stylesheet_pack_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>

【讨论】:

以上是关于ROR Cropper JS 在本地工作,但不在 heroku的主要内容,如果未能解决你的问题,请参考以下文章

Vue.js 过滤器在本地工作,但不在服务器上

ajax json 在本地但不在远程服务器上工作

为啥在php中使用cropper js上传图像时需要不工作

cropper.js 遇到问题

移动端图片裁剪上传—jQuery.cropper.js

在服务器上调用 PHP 函数但在本地服务器上工作时找不到 JS 函数