Handle 413 responses from Nginx when uploading files too large

Fixes #5171
This commit is contained in:
Frédéric Guillot 2023-04-14 20:11:51 -07:00 committed by Frédéric Guillot
parent 0b1c2011ed
commit bd50288030
3 changed files with 17 additions and 4 deletions

View File

@ -35,7 +35,7 @@ return new DomManipulation(tag)};KB.find=function(selector){var element=document
return null};KB.exists=function(selector){return!!document.querySelector(selector)};KB.focus=function(selector){var element=document.querySelector(selector);if(element){return element.focus()}};KB.html.label=function(label,id){return KB.dom('label').attr('for',id).text(label).build()};KB.html.radio=function(label,name,value){return KB.dom('label').add(KB.dom('input').attr('type','radio').attr('name',name).attr('value',value).build()).text(label).build()};KB.html.radios=function(items){var html=KB.dom('div');for(var item in items){if(items.hasOwnProperty(item)){html.add(KB.html.radio(item.label,item.name,item.value))}}};KB.http.request=function(method,url,headers,body){var successCallback=function(){};var authErrorCallback=function(){};var netErrorCallback=function(){};var errorCallback=function(){};function parseResponse(request){var redirect=request.getResponseHeader('X-Ajax-Redirect');var location=request.getResponseHeader('Location');if(redirect==='self'){window.location.reload()}else if(redirect&&redirect.indexOf('#')>-1){window.location=redirect.split('#')[0]}else if(redirect){window.location=redirect}else if(location){window.location=location}else if(request.getResponseHeader('Content-Type')==='application/json'){try{return JSON.parse(request.responseText)}catch(e){}}
return request.responseText}
this.execute=function(){var request=new XMLHttpRequest();request.open(method,url,!0);request.setRequestHeader('X-Requested-With','XMLHttpRequest');for(var header in headers){if(headers.hasOwnProperty(header)){request.setRequestHeader(header,headers[header])}}
request.onerror=function(){errorCallback()};request.onreadystatechange=function(){if(request.readyState===XMLHttpRequest.DONE){var response=parseResponse(request);switch(request.status){case 200:successCallback(response);return;case 401:authErrorCallback(response);errorCallback(response);break;case 0:netErrorCallback(response);errorCallback(response);break;default:errorCallback(response);break}}};request.send(body);return this};this.success=function(callback){successCallback=callback;return this};this.authError=function(callback){authErrorCallback=callback;return this};this.netError=function(callback){netErrorCallback=callback;return this};this.error=function(callback){errorCallback=callback;return this}};KB.http.get=function(url){return(new KB.http.request('GET',url)).execute()};KB.http.postJson=function(url,body){var headers={'Content-Type':'application/json','Accept':'application/json'};return(new KB.http.request('POST',url,headers,JSON.stringify(body))).execute()};KB.http.postForm=function(url,formElement){var formData=new FormData(formElement);return(new KB.http.request('POST',url,{},formData)).execute()};KB.http.uploadFile=function(url,file,csrf,onProgress,onComplete,onError,onServerError){var fd=new FormData();fd.append('files[]',file);fd.append('csrf_token',csrf);var xhr=new XMLHttpRequest();xhr.upload.addEventListener('progress',onProgress);xhr.upload.addEventListener('error',onError);xhr.open('POST',url,!0);xhr.setRequestHeader('X-Requested-With','XMLHttpRequest');xhr.onreadystatechange=function(){if(xhr.readyState===XMLHttpRequest.DONE){if(xhr.status===200){onComplete()}else if(typeof onServerError!=='undefined'){onServerError(JSON.parse(xhr.responseText))}}};xhr.send(fd)};(function(){var isOpen=!1;function onOverlayClick(e){if(e.target.matches('#modal-overlay')){e.stopPropagation();e.preventDefault();destroy()}}
request.onerror=function(){errorCallback()};request.onreadystatechange=function(){if(request.readyState===XMLHttpRequest.DONE){var response=parseResponse(request);switch(request.status){case 200:successCallback(response);return;case 401:authErrorCallback(response);errorCallback(response);break;case 0:netErrorCallback(response);errorCallback(response);break;default:errorCallback(response);break}}};request.send(body);return this};this.success=function(callback){successCallback=callback;return this};this.authError=function(callback){authErrorCallback=callback;return this};this.netError=function(callback){netErrorCallback=callback;return this};this.error=function(callback){errorCallback=callback;return this}};KB.http.get=function(url){return(new KB.http.request('GET',url)).execute()};KB.http.postJson=function(url,body){var headers={'Content-Type':'application/json','Accept':'application/json'};return(new KB.http.request('POST',url,headers,JSON.stringify(body))).execute()};KB.http.postForm=function(url,formElement){var formData=new FormData(formElement);return(new KB.http.request('POST',url,{},formData)).execute()};KB.http.uploadFile=function(url,file,csrf,onProgress,onComplete,onError,onServerError,onRequestTooLarge){var fd=new FormData();fd.append('files[]',file);fd.append('csrf_token',csrf);var xhr=new XMLHttpRequest();xhr.upload.addEventListener('progress',onProgress);xhr.upload.addEventListener('error',onError);xhr.open('POST',url,!0);xhr.setRequestHeader('X-Requested-With','XMLHttpRequest');xhr.onreadystatechange=function(){if(xhr.readyState===XMLHttpRequest.DONE){if(xhr.status===200){onComplete()}else if(xhr.status===413){if(typeof onRequestTooLarge!=='undefined'){onRequestTooLarge()}else{onError(xhr.responseText)}}else if(typeof onServerError!=='undefined'){onServerError(JSON.parse(xhr.responseText))}}};xhr.send(fd)};(function(){var isOpen=!1;function onOverlayClick(e){if(e.target.matches('#modal-overlay')){e.stopPropagation();e.preventDefault();destroy()}}
function onCloseButtonClick(){KB.trigger('modal.close')}
function onFormSubmit(){KB.trigger('modal.loading');submitForm()}
function getForm(){return document.querySelector('#modal-content form:not(.js-modal-ignore-form)')}
@ -100,6 +100,7 @@ return button.text(options.submitLabel).build()}
this.render=function(){KB.on('modal.stop',onStop);KB.on('modal.close',function(){KB.removeListener('modal.stop',onStop)});var element=KB.dom('div').attr('class','form-actions').add(buildButton()).text(' '+options.orLabel+' ').add(KB.dom('a').attr('href','#').click(onCancel).text(options.cancelLabel).build()).build();containerElement.appendChild(element)}});KB.component('external-task-view',function(containerElement,options){this.render=function(){KB.dom(containerElement).html('<div id="external-task-view"><i class="fa fa-spinner fa-2x fa-pulse"></div>');$.ajax({cache:!1,url:options.url,success:function(data){KB.dom(containerElement).html('<div id="external-task-view">'+data+'</div>')}})}});KB.component('file-upload',function(containerElement,options){var inputFileElement=null;var dropzoneElement=null;var files=[];var currentFileIndex=0;function onProgress(e){if(e.lengthComputable){var progress=e.loaded/e.total;var percentage=Math.floor(progress*100);KB.find('#file-progress-'+currentFileIndex).attr('value',progress);KB.find('#file-percentage-'+currentFileIndex).replaceText('('+percentage+'%)')}}
function onError(){var errorElement=KB.dom('div').addClass('file-error').text(options.labelUploadError).build();KB.find('#file-item-'+currentFileIndex).add(errorElement)}
function onServerError(response){var errorElement=KB.dom('div').addClass('file-error').text(response.message).build();KB.find('#file-item-'+currentFileIndex).add(errorElement);KB.trigger('modal.stop')}
function onRequestTooLarge(){var label=options.labelOversize?options.labelOversize:options.labelUploadError;var errorElement=KB.dom('div').addClass('file-error').text(label).build();KB.find('#file-item-'+currentFileIndex).add(errorElement)}
function onComplete(){currentFileIndex++;if(currentFileIndex<files.length){KB.http.uploadFile(options.url,files[currentFileIndex],options.csrf,onProgress,onComplete,onError,onServerError)}else{KB.trigger('modal.stop');KB.trigger('modal.hide');var alertElement=KB.dom('div').addClass('alert').addClass('alert-success').text(options.labelSuccess).build();var buttonElement=KB.dom('button').attr('type','button').addClass('btn').addClass('btn-blue').click(onCloseWindow).text(options.labelCloseSuccess).build();KB.dom(dropzoneElement).replace(KB.dom('div').add(alertElement).add(buttonElement).build())}}
function onCloseWindow(){window.location.reload()}
function onSubmit(){currentFileIndex=0;uploadFiles()}
@ -109,7 +110,7 @@ function onClickFileBrowser(){files=[];currentFileIndex=0;inputFileElement.click
function onDragOver(e){e.stopPropagation();e.preventDefault()}
function onDrop(e){e.stopPropagation();e.preventDefault();for(var i=0;i<e.dataTransfer.files.length;i++){files.push(e.dataTransfer.files[i])}
showFiles()}
function uploadFiles(){if(files.length>0){KB.http.uploadFile(options.url,files[currentFileIndex],options.csrf,onProgress,onComplete,onError,onServerError)}}
function uploadFiles(){if(files.length>0){KB.http.uploadFile(options.url,files[currentFileIndex],options.csrf,onProgress,onComplete,onError,onServerError,onRequestTooLarge)}}
function showFiles(){if(files.length>0){KB.trigger('modal.enable');KB.dom(dropzoneElement).empty().add(buildFileListElement())}else{KB.trigger('modal.disable');KB.dom(dropzoneElement).empty().add(buildInnerDropzoneElement())}}
function buildFileInputElement(){return KB.dom('input').attr('id','file-input-element').attr('type','file').attr('name','files[]').attr('multiple',!0).on('change',onFileChange).hide().build()}
function buildInnerDropzoneElement(){var dropzoneLinkElement=KB.dom('a').attr('href','#').text(options.labelChooseFiles).click(onClickFileBrowser).build();return KB.dom('div').attr('id','file-dropzone-inner').text(options.labelDropzone+' '+options.labelOr+' ').add(dropzoneLinkElement).build()}

View File

@ -25,6 +25,12 @@ KB.component('file-upload', function (containerElement, options) {
KB.trigger('modal.stop');
}
function onRequestTooLarge() {
var label = options.labelOversize ? options.labelOversize : options.labelUploadError;
var errorElement = KB.dom('div').addClass('file-error').text(label).build();
KB.find('#file-item-' + currentFileIndex).add(errorElement);
}
function onComplete() {
currentFileIndex++;
@ -92,7 +98,7 @@ KB.component('file-upload', function (containerElement, options) {
function uploadFiles() {
if (files.length > 0) {
KB.http.uploadFile(options.url, files[currentFileIndex], options.csrf, onProgress, onComplete, onError, onServerError);
KB.http.uploadFile(options.url, files[currentFileIndex], options.csrf, onProgress, onComplete, onError, onServerError, onRequestTooLarge);
}
}

View File

@ -108,7 +108,7 @@ KB.http.postForm = function (url, formElement) {
return (new KB.http.request('POST', url, {}, formData)).execute();
};
KB.http.uploadFile = function (url, file, csrf, onProgress, onComplete, onError, onServerError) {
KB.http.uploadFile = function (url, file, csrf, onProgress, onComplete, onError, onServerError, onRequestTooLarge) {
var fd = new FormData();
fd.append('files[]', file);
fd.append('csrf_token', csrf);
@ -123,6 +123,12 @@ KB.http.uploadFile = function (url, file, csrf, onProgress, onComplete, onError,
if (xhr.readyState === XMLHttpRequest.DONE) {
if (xhr.status === 200) {
onComplete();
} else if (xhr.status === 413) {
if (typeof onRequestTooLarge !== 'undefined') {
onRequestTooLarge();
} else {
onError(xhr.responseText);
}
} else if (typeof onServerError !== 'undefined') {
onServerError(JSON.parse(xhr.responseText));
}