javascript 使用 Ruby on Rails 拖放上传 HTML5 文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12774394/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-26 17:05:46  来源:igfitidea点击:

HTML5 file drag-and-drop upload with Ruby on Rails

javascriptruby-on-railsrubyhtml

提问by user1436111

In my Ruby on Rails app, I have a simple file upload button that I'm trying to replace with a drag and drop box using the File/FileReader APIs in HTML5, using this tutorialspecifically. As is, I use a Ruby script to upload the file to my public/data folder. I'm not sure how to integrate the drag-and-drop script with that. My idea was to make the file upload button I had already hidden, and use Javascript to set its value to the path of the drag-and-dropped image when the user tries to submit.

在我的 Ruby on Rails 应用程序中,我有一个简单的文件上传按钮,我正在尝试使用 HTML5 中的 File/FileReader API 将其替换为拖放框,具体使用本教程。照原样,我使用 Ruby 脚本将文件上传到我的 public/data 文件夹。我不确定如何将拖放脚本与它集成。我的想法是让我已经隐藏的文件上传按钮,并在用户尝试提交时使用Javascript将其值设置为拖放图像的路径。

However, when I try to submit I get the error:

但是,当我尝试提交时,出现错误:

File name too long - public/data/data:image/jpeg;base64,/9j/4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAAAP/sABFEdWNreQABAAQAAABkAAD/4QMtaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wLwA8P3hwYWNj....

文件名太长 - public/data/data:image/jpeg;base64,/9j/4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAAAP/sABFEdWNreQABAAQAAABkAAD/4QMtaHR0cDovL25zLmFkb2JlLmNvbS94YXAvYAWjw....

because the temporary file storage name given by HTML5 is just too long, I guess.

因为 HTML5 给出的临时文件存储名称太长了,我猜。

I tried concatenating the string to the first 60 characters and then it gave the error:

我尝试将字符串连接到前 60 个字符,然后它给出了错误:

No such file or directory - public/data/data:image/jpeg;base64,/9j/4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAAA

没有这样的文件或目录 - public/data/data:image/jpeg;base64,/9j/4QAYRXhpZgAASUkqAAgAAAAAAAAAAAAA

In any case, the file is not getting added to public/datafolder.

在任何情况下,该文件都不会被添加到public/data文件夹中。

My HTML:

我的 HTML:

<%= form_tag( { :action => 'create' }, :multipart => true ) %>
<div id="dropbox"><span id="droplabel">Drop file here...</span></div>
<img id="preview" alt="[ preview will display here ]" />

<%= hidden_field_tag :uploadfile, :id => "uploadfile", :name => "uploadfile" %>
<br /><br />
<div id="submit">
<%= submit_tag( "Upload file" ) %>
</div>

Ruby:

红宝石:

def create
    name = params[:uploadfile]
    directory = "public/data"
    path = File.join(directory, name)
    File.open(path, "wb") { |f| f.write(params[:uploadfile].read) }
     @project = Project.new({:filename => name, :location => path})

    respond_to do |format|
      if @project.save
        format.html { redirect_to @project, notice: 'Project was successfully created.' }
        format.json { render json: @project, status: :created, location: @project }
      else
        format.html { render action: "new" }
        format.json { render json: @project.errors, status: :unprocessable_entity }
      end
    end
  end

and JS:

和JS:

$("#submit input").click(function() {
    $("#uploadfile").val($("#preview").attr("src"));
});

回答by Levi V

The problem looks like you are sending the file as a Base64 encoded Data URL, which is fine, but the filename doesn't go along with it when you POST to the server. You may want extract the filename before converting the file to a Data URL so you can send it along with the file in the params. Or, create a new filename (UUID) like Madao suggested.

问题看起来像您将文件作为 Base64 编码的数据 URL 发送,这很好,但是当您 POST 到服务器时,文件名不伴随它。您可能希望在将文件转换为数据 URL 之前提取文件名,以便您可以将其与 params 中的文件一起发送。或者,像 Madao 建议的那样创建一个新的文件名 (UUID)。

This should at least fix your filename problem:

这至少应该解决您的文件名问题:

def create
    ##
    file = params[:uploadfile]
    name = params[:filename] || SecureRandom.uuid
    ##
    directory = "public/data"
    path = File.join(directory, name)
    File.open(path, "wb") { |f| f.write(file.read) }
    @project = Project.new({:filename => name, :location => path})

    respond_to do |format|
      if @project.save
        format.html { redirect_to @project, notice: 'Project was successfully created.' }
        format.json { render json: @project, status: :created, location: @project }
      else
        format.html { render action: "new" }
        format.json { render json: @project.errors, status: :unprocessable_entity }
      end
    end
  end

回答by Madao

The point is use params[:uploadfile] as name value is unnecessary, if you want a unique key you can just use SecureRandom.uuid.

重点是使用 params[:uploadfile] 作为 name 值是不必要的,如果你想要一个唯一的键,你可以使用SecureRandom.uuid.