をアップロード私はいくつかの困難に遭遇しました。Railsは大容量のファイル
使用しているサーバーは:pumaです。
ファイル転送は速度です(ローカルネットワーク(ギガビット)ではajax xhrの進行が続きます)。
ただし、ファイル/ tmp/RackMultipart *の保存には時間がかかりました。
ファイルがRackによってメモリにロードされ、そのプロセスが/ tmp /に保存されているとします。その後、コントローラは処理を進める。
コードは画像のような小さなファイルでも機能します。
しかし、実行完了は約1分ほどかかる大きなファイル> 100 Moのため
...マイコード:
アップロードエリア: ビュー/ _attachments.html.erb
<div class="card">
<div class="card-header">
Fichiers
</div>
<div class="card-block">
<span id="attachment-area-message"></span>
<div id="attachment-area">
Déposez vos fichiers ici
</div>
<!-- Area for progress bar -->
<div id="progress-wrapper"></div>
<script>
var attachment_token = '<%= form_authenticity_token %>';
var attachment_model_name = '<%= fileable.class.name %>';
var attachment_model_id = '<%= fileable.id %>';
</script>
</div>
<div class="card-block">
<div class="attachfiles-wrapper">
<div id="attachfiles">
<% fileable.attachments.includes('user').order(created_at: :asc).each do |attachment| %>
<%= render partial: 'app/attachments/attachment', locals: { attachment: attachment } %>
<% end %>
</div>
</div>
</div>
</div>
アップロードを開始するJSファイル:
$(document).on('turbolinks:load', function() {
new Clipboard('.btn-clipboard');
var upload_mime = [
'application/zip',
// Image
'image/png',
'image/jpeg',
'image/gif',
'image/tiff',
'image/svg+xml',
];
var upload_maxSize = 3000000000;
var server_url = '/app/attachments/upload.js'; // Route for upload file, .js for the js call back
var element = $("#attachment-area");
// EVENTS
// ----------------------------------------------------------------------------
element.on('dragover', function(e) {
e.preventDefault();
e.stopPropagation();
});
element.on('dragenter', function(e) {
element.addClass('active');
e.preventDefault();
e.stopPropagation();
});
element.on('dragleave', function(e) {
element.removeClass('active');
e.preventDefault();
e.stopPropagation();
});
element.on('drop', function(e) {
element.removeClass('active');
e.preventDefault();
e.stopPropagation();
if (e.originalEvent.dataTransfer){
if (e.originalEvent.dataTransfer.files.length > 0) {
console.log(e.originalEvent.dataTransfer.files);
upload(e.originalEvent.dataTransfer.files);
}
}
return false;
});
// UPLOADS
// ----------------------------------------------------------------------------
var upload = function(files) {
// Send each file
$.each(files, function(key, file) {
// TEST THE FILE
// ----------------------
var FileValidate = true;
// Size
if(file.size > upload_maxSize) {
$('#attachment-area-message').append(file.name + " : Fichier trop lourd (3 Go maximum) : " + file.size);
FileValidate = false;
}
// Mime type
if(upload_mime.indexOf(file.type) == -1) {
$('#attachment-area-message').append(file.name + " : Type de fichier non authorisé : " + file.type);
$('#attachment-area-message').append("<br>Essayez de zipper le fichier");
FileValidate = false;
}
if(!FileValidate) return true; // Continue to next iteration
// SEND FILE
// ----------------------
console.log(file);
var formData = new FormData();
formData.append('attachment[file]', file);
formData.append("attachment[model_name]", attachment_model_name);
formData.append("attachment[model_id]", attachment_model_id);
console.log(formData);
// Progress Bar Name
var progress_name = file.name.replace(/[^a-zA-Z]/g,'-').toLowerCase();
// Send the request :)
$.ajax({
url: server_url,
data: formData,
type: 'POST',
beforeSend: function(request) {
request.setRequestHeader('X-CSRF-Token', attachment_token);
console.log('BEFORE SEND');
},
contentType: false, // NEEDED, DON'T OMIT THIS (requires jQuery 1.6+)
processData: false, // NEEDED, DON'T OMIT THIS
xhr: function() {
// create an XMLHttpRequest
var xhr = new XMLHttpRequest();
console.log('xhr');
xhr.upload.onprogress = function (e) {
console.log('xhr progress');
if (e.lengthComputable) {
var percente = Math.round((e.loaded * 100)/e.total);
$('.' + progress_name + ' .progress-bar').width(percente + "%");
}
};
xhr.onloadstart = function (e) {
console.log('xhr onloadstart');
$('#progress-wrapper').append('<div class="' + progress_name + '" style="margin-top:5px;">'
+ '<span class="description">' + file.name + '</span>'
+ '<div class="progress" id="file-upload-bar">'
+ '<div class="progress-bar bg-info" role="progressbar" style="width:0%; height:10px;" aria-valuenow="50" aria-valuemin="0" aria-valuemax="100"></div>'
+ '</div></div>');
};
xhr.onload = function (e) {
console.log('xhr onload');
if (xhr.status === 200) eval(xhr.responseText); // Grab the return of rails controller (format.js)
};
xhr.onloadend = function (e) {
console.log('xhr onloadend');
$('.' + progress_name).remove();
};
return xhr;
}
});
});
};
});
コントローラ:
(アタッチメントモデルは、ファイル可能な多形ベースです)。
class App::AttachmentsController < AppController
before_action :find_fileable
def upload
# Get the File
uploaded_io = attach_params[:file]
logger.debug '---------'
logger.debug params.inspect
logger.debug '---------'
# Define file destination
dest = Rails.root.join('public', 'uploads', 'attachments', attach_params[:model_name], attach_params[:model_id], uploaded_io.original_filename)
file_name = uploaded_io.original_filename
file_basename = File.basename(uploaded_io.original_filename, '.*')
file_extname = File.extname(uploaded_io.original_filename)
# Make dir
dir = File.dirname(dest)
FileUtils.mkdir_p(dir) unless File.directory?(dir)
# Test if file exist (and update version if needed)
if File.exist?(dest)
version = 0
loop do
version += 1
file_name = file_basename + '-' + version.to_s + file_extname
dest = Rails.root.join('public', 'uploads', 'attachments', attach_params[:model_name], attach_params[:model_id], file_name)
break if !File.exist?(dest)
end
end
# Copy file to dest
#FileUtils.cp uploaded_io.path, dest
File.open(dest, 'wb') do |file|
file.write(uploaded_io.read)
end
# Save in database
@attach = @fileable.attachments.new
@attach.user_id = @current_user.id
@attach.name = file_name
@attach.size = uploaded_io.size
@attach.mime = uploaded_io.content_type
@attach.key = Digest::SHA1.hexdigest([Time.now, rand].join)
respond_to do |format|
if @attach.save
flash[:success] = "Fichier ajouté"
format.js # upload.js callback add new file to the list of files
else
flash[:warning] = "Fichier non enregistré :("
end
end
end
private
def attach_params
params.require(:attachment).permit(:model_id, :model_name, :file)
end
def find_fileable
@fileable = Task.find_by_id(attach_params[:model_id]) if attach_params[:model_name] == 'Task'
end
end
私は別のファイル管理ソリューションをテストした:CarrierWave、神社、...
は、残念ながら、問題がまだそこにあります。常にラックは前方に保管してください。 ヘルプや考え方はありますか?私はこの "ラック"を食べたい
ありがとう、 Seb。
が問題ですアップロードに時間がかかりすぎる、または完了しない –
こんにちはアロン。数分後にアップロードが完了します。問題は時間です:) – Oncleroger