Я работаю над приложением, в которое мы загружаем около 200-300 изображений с помощью jquery fileupload. Перед загрузкой мне нужно изменить его размер, используя canvas в браузере, чтобы уменьшить нагрузку на сервер. Но страница вылетает после загрузки примерно 150 фотографий и получения ошибки Aww snap! smoething went wrong
Вот код JavaScript, который я использую для изменения размера и загрузки файлов,
<script>
$(document).ready(function(){
function formatBytes(bytes, decimals = 2) {
if (bytes === 0) return '0 Bytes';
const k = 1024;
const dm = decimals < 0 ? 0 : decimals;
const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
const i = Math.floor(Math.log(bytes) / Math.log(k));
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
}
/* Utility function to convert a canvas to a BLOB */
var dataURLToBlob = function(dataURL) {
var BASE64_MARKER = ';base64,';
if (dataURL.indexOf(BASE64_MARKER) == -1) {
var parts = dataURL.split(',');
var contentType = parts[0].split(':')[1];
var raw = parts[1];
return new Blob([raw], {type: contentType});
}
var parts = dataURL.split(BASE64_MARKER);
var contentType = parts[0].split(':')[1];
var raw = window.atob(parts[1]);
var rawLength = raw.length;
var uInt8Array = new Uint8Array(rawLength);
for (var i = 0; i < rawLength; ++i) {
uInt8Array[i] = raw.charCodeAt(i);
}
return new Blob([uInt8Array], {type: contentType});
}
/* End Utility function to convert a canvas to a BLOB */
$("#fileupload").change(function(e){
e.preventDefault();
$('.loader_image, .loader_text').removeClass('hide');
for (var i = 0; i < this.files.length; i++){
var file = this.files[i];
var reader = new FileReader();
reader.onload = function (readerEvent) {
var image = new Image();
image.onload = function (imageEvent) {
// Resize the image
var canvas = document.createElement('canvas'),
max_size = 1600,// TODO : pull max size from a site config
width = image.width,
height = image.height;
if (width > height) {
if (width > max_size) {
height *= max_size / width;
width = max_size;
}
} else {
if (height > max_size) {
width *= max_size / height;
height = max_size;
}
}
canvas.width = width;
canvas.height = height;
canvas.getContext('2d').drawImage(image, 0, 0, width, height);
var mimeType = image.src.match(/[^:]\w+\/[\w-+\d.]+(?=;|,)/)[0];
var ext = image.src.match(/[^:/]\w+(?=;|,)/)[0];
var dataUrl = canvas.toDataURL(mimeType);
var resizedImage = dataURLToBlob(dataUrl);
image_html = '<div class="col-sm-2 sm-margin-bottom-30 image_subcontainer" style="margin-bottom: 20px;" data-filename="'+imageEvent.target.name+'"><p class="album-btn" align="right" style=""><a class="remove_photo" role="button" style="color:grey;" rel="nofollow" href="#"> </a></p><p></p><a href="#" class="fancybox img-hover-v1"><span style="height: 140px; padding-top: 14px;"><img src="'+image.src+'"></span></a><div style="text-align: center;margin-bottom: 30px;">'+imageEvent.target.name+'</div> <div id="progress" class="col-sm-2 sm-margin-bottom-27" style="padding-bottom: 10px;"><div class="bar" style="width: 0%;"></div><span class="data_loaded"></span></div></div>'
$('.images_fancybox').prepend(image_html);
$('#fileupload').fileupload('add', {files: [new File([resizedImage], imageEvent.target.name)]})
}
image.name = readerEvent.target.fileName;
image.src = readerEvent.target.result;
}
reader.fileName = file.name;
reader.readAsDataURL(file);
}
});
$('#fileupload').fileupload({
dataType: 'json',
add: function (e, data) {
var fileType = data.files[0].name.split('.').pop().toLowerCase(), allowdtypes = 'jpeg,jpg,png';
if (allowdtypes.indexOf(fileType) < 0) {
alert('Invalid file type '+fileType+'. Allowed file types: jpeg,jpg,png ');
return false;
}
if(data.fileInput == undefined){
data.submit()
}
// console.log(data);
},
start: function (e) {
// progressBar = '<div id="progress" class="col-sm-2 sm-margin-bottom-30"><div class="bar progress-bar-warning" style="width: 0%;"></div></div>'
// $('#progress_bar').append(progressBar);
},
progressall: function (e, data) {
if(data.loaded == data.total){
$('.loader_image, .loader_text').addClass('hide');
}
},
progress: function (e, data) {
var progress = parseInt(data.loaded / data.total * 100, 10);
$('div[data-filename="'+data.files[0].name+'"] #progress .bar, div[data-filename="'+data.files[0].name+'"] #progress').css(
'width',
progress + '%'
);
$('div[data-filename="'+data.files[0].name+'"] #progress .data_loaded').text(formatBytes(data.loaded) + "/" + formatBytes(data.total))
},
done: function (e, data) {
if(data.result.success){
var uploaded_image = imageContainer(data.result.id, data.result.album_id, data.result.filename, data.result.fileurl, data.result.authenticity_token)
// $('div[data-filename="'+data.result.filename+'"]').remove();
// $('.images_fancybox').prepend(uploaded_image);
$('div[data-filename="'+data.files[0].name+'"]').replaceWith(uploaded_image);
SP.Photo.bindEvents();
SP.Photo.initNoteForm();
SP.App.initFancybox();
}else{
$('.container_wrapper .flash_messages').html(data.result.error_html)
}
},
fail: function(e, data){
console.log(data);
},
always: function(e, data){
console.log(data);
},
});
function imageContainer(id, album_id, filename, fileurl, authenticity_token){
return '<div class="col-sm-2 sm-margin-bottom-30 image_subcontainer" data-photo-id="'+id+'" style="margin-bottom: 20px;"><p class="album-btn" align="right" style=""><a data-toggle="tooltip" data-placement="top" data-original-title="Delete photo" class="remove_photo tooltips glyphicon glyphicon-remove" role="button" data-confirm="Your are attemtping to delete a photo. Press "Ok" to delete or "Cancel" to cancel the request." style="color:grey;" data-remote="true" rel="nofollow" data-method="delete" href="/photographer/albums/'+album_id+'/photos/'+id+'"></a><a data-id="'+id+'" class="add_note_btn add_note_'+id+' pull-left glyphicon glyphicon-edit " style="color:grey;" href="#" data-original-title="" title=""></a></p><div style="display: none;" class="add_note_class_'+id+'"><div class="row"><div class="col-sm-12"><form class="note_form" data-id="'+id+'" id="edit_photo_'+id+'" action="/photographer/albums/'+album_id+'/photos/'+id+'" accept-charset="UTF-8" method="post"><input name="utf8" type="hidden" value="✓"><input type="hidden" name="_method" value="put"><input type="hidden" name="authenticity_token" value="'+authenticity_token+'"><fieldset><div id="status-area" data-id="'+id+'"></div><div class="row"><section class="col col-12"><textarea rows="3" style="resize:vertical;" class="form-control note_input_'+id+'" name="photo[photographer_note]" id="photo_photographer_note"></textarea></section></div></fieldset><br><fieldset><div class="row"><img class="loader_image hide pull-left" src="/assets/loader.gif" alt="Loader" width="30" height="30"><input type="submit" name="commit" value="Submit" class="btn btn-info pull-right" data-disable-with="Submit"></div></fieldset></form></div><div class="row"><div class="col-sm-12"></div></div><div class="row"><div class="col-sm-12"></div></div></div></div><p></p><a href="'+fileurl+'" data-fancybox="gallery" data-caption="'+filename+'" class="fancybox img-hover-v1" title="'+filename+'" id="'+id+'" data-user="suggested" data-album-id="'+album_id+'"><span style="height: 140px; padding-top: 14px;"><img class="img-responsive" src="'+fileurl+'"></span></a><!-- word-wrap: break-word; --><div style="text-align: center;">'+filename+'</div><div style="padding-bottom: 30px;"><a data-id="suggested_'+id+'" class="suggested_'+id+'" data-remote="true" href="/photographer/albums/'+album_id+'/photos/'+id+'/suggest"><button type="button" class=" btn-warning pull-left btn-circle"><i class="glyphicon "></i></button></a><a href="#"><button type="button" class=" btn-success pull-right btn-circle"><i class="glyphicon "></i></button></a></div></div>'
}
});
</script>