admin管理员组

文章数量:1312823

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 tutorial specifically. 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.

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

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

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

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

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

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

My 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:

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

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 tutorial specifically. 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.

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

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

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

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

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

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

My 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:

$("#submit input").click(function() {
    $("#uploadfile").val($("#preview").attr("src"));
});
Share Improve this question edited Jun 16, 2017 at 2:24 Gleb Kemarsky 10.4k7 gold badges46 silver badges71 bronze badges asked Oct 8, 2012 at 1:44 user1436111user1436111 2,1417 gold badges24 silver badges41 bronze badges 2
  • 1 I should remend you this gem: blueimp.github./jQuery-File-Upload Take it for a try, I think the implementation is very straight forward. Just take a look on the ruby documentation. – Jorge Najera T Commented Oct 8, 2012 at 8:12
  • It's awesome, but this is not a gem it's a jquery plugin. The wiki [github./blueimp/jQuery-File-Upload/wiki] refers to many ruby examples and one gem though, [github./tors/jquery-fileupload-rails] – AndreDurao Commented Jul 28, 2014 at 12:39
Add a ment  | 

2 Answers 2

Reset to default 1

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.

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

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

本文标签: javascriptHTML5 file draganddrop upload with Ruby on RailsStack Overflow