이 문제는 여러 시간 동안 저를 괴롭 혔으며 해결 방법을 찾지 못하는 것 같습니다.레일즈 3.2 및 AJAX (플래시 이외의 업로드 솔루션)를 사용하여 여러 파일을 Amazon S3에 직접 업로드
저는 사용자가 carrierwave_direct, fog 및 carrierwave (carrierwave_direct에 대한 종속성)를 사용하여 Amazon S3 계정에 파일을 업로드 할 수있는 3.2 레일 앱이 있습니다. carrierwave_direct를 사용하면 Amazon S3에 직접 게시하여 서버로 파일 업로드를 건너 뛸 수 있습니다 (대용량 파일의 경우 Heroku와 같은 서버 처리 및 시간 초과가 저장됩니다).
1 개의 파일을 선택하고 Amazon으로 업로드 한 다음 Amazon에 제공 한 URL로 redirect_를 보내고 싶다면 잘 작동합니다. Amazon S3에 양식을 게시하면 Amazon이 양식에이 URL을 지정한 URL에 응답하고 모델의 Amazon에있는 파일에 대한 포인터로 저장됩니다.
수명주기는 다음과 같습니다. 파일 1 개 선택, Amazon에서 POST, Amazon에서 사용자를 다른 페이지로 보내는 URL로 응답 한 다음 Amazon 파일 포인터로 레코드를 저장할 수 있습니다.
여러 파일을 선택하고 업로드하고 업로드 진행률을 업데이트하는 방법은 무엇입니까? 나는 현대적인 브라우저에서 제공하는 파일 API를 사용하여 순수한 자바 스크립트로이 작업을 시도하고 있으므로 타사 도구가 필요하지 않습니다. 또한 깊이있는 학습을 위해 모든 플러그인을 피하고 직접 코드를 작성하려고합니다.
내가 얻기 위해 노력하고있어 기능은 다음과 같습니다
- 사용자는 파일 필드 (또는 드래그/드롭)
- 사용자가 여러 파일을 선택하여 양식을보고 (중 파일 필드 또는 드래그/드롭 클릭) 을 큐에있는 각 파일을 통해 자바 스크립트 (아무 서버 아직), 업로드
- 사용자가 다음 "시작 업로드"를 클릭 (단지 브라우저 파일 API를 사용하여 파일 이름과 크기)을 선택한 파일의 큐를 구축 버튼
- 으로 반복 사용
- ~ d 파일을 Amazon S3에 POST합니다. Amazon은 각 POST에 URL을 사용하여 응답하며 URL은 표준 요청이 아닌 Javascript를 통해 처리해야합니다. Amazon에서 제공 한 URL은 Amazon 파일에 대한 포인터를 저장하는 레코드를 생성합니다. 일단 레코드가 생성되면 코드는 완료 될 때까지 대기열의 다음 파일로 이동합니다.
이 시점에서 개별 진행 막대를 사용하지 않고도 할 수 있습니다. 페이지를 새로 고치지 않고 Amazon S3에 여러 파일을 게시하면됩니다.
나는 보석에 부분적이지 않다. 나는 실제로 그것이 특정한 방법으로 끝나기를 원한다면 내가하고 싶은 일을 처음부터 다시 써야 할 것 같아 두려워합니다. 목표는 AJAX를 통해 Amazon S3 계정에 여러 파일을 업로드하는 것입니다. 문제에 접근하는 일반적인 개념조차도 나는 황홀 할 것이다. 나는 많은 시간을 인터넷 검색을 통해 보냈으며, 나는 내가 원하는 것을 해결할만한 해결책을 찾지 못했다. 어떤 도움이라도 대단히 감사하겠습니다.
편집 2014년 3월 2일
주권은 내가 여러 업로드를 구현하는 방법을 물었다. 너무 오랫동안 나는 왜 내가했던 일 (아마도 어쨌든 처음에는 그랬듯이 나쁜 코드 일 것임) 뒤에 모든 "왜"를 떠 올리지 못했지만, 여기에 내가 무엇을했는지가 여기에있다.
내가 업로드 한 모델은 회원 이미지이며 Amazon S3에 저장된 이미지입니다.그것은 사용자가 여러 이미지를 선택할 수있게 해주었습니다. 실제로 이미지로 변환 한 PDF 파일이라고 생각하고 화면에 드래그/드롭합니다. 업로드하는 동안 사용자에게 얼마나 오래 걸릴지에 대한 피드백을 제공하는 모달을 표시했습니다.
나는이 일을 많이 기억하지 못하지만, 그것을 자유롭게 사용하면 도움이된다.
# app/views/testimonials/new.html.erb
<div id="main" class="padded">
<div class="center">
<div id="dropzone">
Click or Drop Files here to Upload
</div>
<%= form_for @testimonial do |f| %>
<div class="field">
<%= file_field_tag :image, multiple: true, name: "testimonial[image]", id: "testimonial_image" %>
</div>
<% end %>
</div>
</div>
<div id="mask"></div>
<div id="modal">
<h1>
Uploading <span id="global-upload-count">0</span> Files...
</h1>
<div id="global-progress">
<div id="global-progress-bar" style="width: 0%">
<div id="global-progress-percentage">0%</div>
</div>
</div>
<div id="global-processing">
<span class="spinner"></span> Processing...<span id="global-processing-count">0</span> sec
</div>
</div>
<script id="template-upload" type="text/x-tmpl">
<div class="upload">
{%=o.name%} ({%=o.readable_size%})
<div class="float-right percentage"></div>
<div class="progress"><div class="bar" style="width: 0%"></div></div>
</div>
</script>
그리고 JS : 여기
# Gemfile
# For client-side multiple uploads
gem "jquery-fileupload-rails"
# For file uploads and Amazon S3 storage
gem "rmagick"
gem "carrierwave"
gem "fog"
뷰의
number_to_human_size = (bytes) ->
sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB']
i = parseInt(Math.floor(Math.log(bytes)/Math.log(1024)))
return Math.round(bytes/Math.pow(1024, i), 2) + ' ' + sizes[i]
dropzone_hover = (e) ->
e.preventDefault()
$(this).addClass("dropzone-hover")
dropzone_leave = (e) ->
e.preventDefault()
$(this).removeClass("dropzone-hover")
jQuery ->
global_count = 0
seconds_to_process = 0
processing_factor = 5 # seconds to convert/process each uploaded file
$("#testimonial_image").hide()
dropzone = $("#dropzone")
dropzone.bind "click", (e) ->
$("#testimonial_image").click()
dropzone.bind("dragover", dropzone_hover)
dropzone.bind("dragleave", dropzone_leave)
dropzone.bind("drop", dropzone_leave)
$("#new_testimonial").data("global-count", "0")
$("#new_testimonial").fileupload
dropZone: $("#dropzone")
maxFileSize: 5000000 # 5 MB
dataType: "script"
add: (e, data) ->
file = data.files[0]
file.readable_size = number_to_human_size(file.size)
data.context = $(tmpl("template-upload", file).trim())
$("#new_testimonial").append(data.context)
data.submit()
global_count += 1
progress: (e, data) ->
if data.context
progress = parseInt(data.loaded/data.total * 100, 10)
data.context.find(".bar").css("width", progress + "%")
data.context.find(".percentage").text(progress + "%")
submit: (e, data) ->
$("#mask").show()
$("#modal").center().show()
progressall: (e, data) ->
$("#global-upload-count").text(global_count)
global_progress = parseInt(data.loaded/data.total * 100, 10)
$("#global-progress-bar").css("width", global_progress + "%")
$("#global-progress-percentage").text(global_progress + "%")
if global_progress >= 100
seconds_to_process = global_count * processing_factor
$("#global-processing-count").text(seconds_to_process)
$("#global-processing").show()
timer = setInterval(->
seconds_to_process = seconds_to_process - 1
$("#global-processing-count").text(seconds_to_process)
if seconds_to_process == 0
clearInterval(timer)
global_count = 0
seconds_to_process = 0
$("#modal, #mask").hide(0)
, 1000)
증언에 모델 :
코멘트에 조언으로class Testimonial < ActiveRecord::Base
mount_uploader :image, ImageUploader
def display_name
if name.blank?
return "Testimonial #{self.id}"
else
return name
end
end
end
다음을 사용하십시오. http://blueimp.github.com/jQuery-File-Upload/ – apneadiving
@apneadiving은 내가 원했던대로 정확하게 작동했습니다. 플러그인 페이지에는 올바른 방향으로 나를 가리키는 유용한 예제가 있었으며 원하는대로 구현했습니다. 의견 대신 질문에 대한 답변을 작성하면 기꺼이 답변을 수락합니다. 대단히 고마워, 너는 내게 많은 노력을 덜어 줬다. –
니스 : – apneadiving