Ошибка при передаче больших файлов на сервер с помощью AJAX POST-запроса (IIS 7, ASP.NET MVC 4) - PullRequest
1 голос
/ 26 сентября 2019

Это мой первый пост в StackOverflow, поэтому я заранее прошу прощения, если мой вопрос в нетрадиционном формате.У меня есть форма на сайте интрасети, которая позволяет пользователю загружать файлы, передавая их на сервер. Ниже приводится функция js, которая передает файл на сервер.Этот код безупречно работает с файлами меньшего размера (проверено до 900 КБ), но файл большего размера (9 МБ) выдает ошибку 500 , даже не достигая сервера.

function UploadDocument(customSectionId, evaluationSectionId) {
    if ($('#eval-attachment-modal-file')[0].files != null) {
        if (customSectionId != null && customSectionId == -1) {
            customSectionId = null;
        }
        if (evaluationSectionId != null && evaluationSectionId == -1) {
            evaluationSectionId = null;
        }
        var file = $('#eval-attachment-modal-file')[0].files[0];
        if (file) {
            var fd = new FormData();
            fd.append("fileToUpload", file);
            fd.append("evalId", EvalId);
            fd.append("customSectionId", customSectionId);
            fd.append("evaluationSectionId", evaluationSectionId);
            fd.append("canUploadImages", @(Model.CanUploadImages ? "true" : "false"));
            fd.append("canUploadDocuments", @(Model.CanUploadDocuments ? "true" : "false"));
            $('#upload-file-button').hide();
            $('#upload-file-spinner').show();
            $.ajax({
                url: '@Url.Action("UploadDocument")',
                type: 'POST',
                datatype: 'json',
                data: fd,
                processData: false,
                contentType: false,
                success: function (response) {
                    if (response != null && response.success) {
                        $('#evaluation-attachment-grid').trigger('reloadGrid');
                        if (evaluationSectionId == @((int) EvaluationSection.ExecutiveSignature)) {
                            var checkbox = $('#ExecutiveSignatureSignedOff');
                            var dateFieldForCheckbox = $('#ExecutiveSignatureSignedOffDate');
                            if (!checkbox.is(':checked')) {
                                checkbox.prop('checked', 'true');
                                dateFieldForCheckbox.val('@(DateTime.Now.ToShortDateString())');
                                SaveEvaluation(function () { AlertSuccess('Executive signature successfully uploaded. Evaluation saved.'); });
                            }
                        }
                    }
                    else {
                        if (response != null) {
                            if (response.errorMessages != null) {
                                for (var i = 0; i < response.errorMessages.length; i++) {
                                    AlertError(response.errorMessages[i]);
                                }
                            }
                        }
                        else {
                            AlertError('Uploading Document Failed. Please contact your I.T. administrator.');
                        }
                    }
                    $('#upload-file-spinner').hide();
                    $('#upload-file-button').show();
                },
                async: true
            });
        }
    }
}

После отладки браузер сообщает, что ошибка произошла в jquery , когда он пытается отправить XMLHttpRequest (взорвана строка xhr.send)

            try {

                // Do send the request (this may raise an exception)
                xhr.send( options.hasContent && options.data || null );
            } catch ( e ) {

                // #14683: Only rethrow if this hasn't been notified as an error yet
                if ( callback ) {
                    throw e;
                }
            }

Один из моих коллегзаявил, что IIS иногда может бороться с вами при попытке передать большие файлы на сервер, поэтому я добавил этот предложенный код в свою веб-конфигурацию безрезультатно

<system.webServer>
<security>
  <requestFiltering>
    <!-- maxAllowedContentLength is in bytes (B)  -->
    <requestLimits maxAllowedContentLength="20971520"/>
    <!-- 20MB -->
  </requestFiltering>
</security>
</system.webServer>

Я подозреваю, что это IIS, но, честно говоря, яУ меня нет идей.Пожалуйста, сообщите СО Сообщество

1 Ответ

1 голос
/ 26 сентября 2019

Как правило, клиент не ограничен размерами файлов, скорее это почти всегда на стороне сервера.Значения по умолчанию в IIS довольно низкие, чтобы люди не могли загружать файлы, на которых запущен ваш сервер.Подумайте, например, об услугах, которые позволяют людям загружать видеофайлы размером в несколько гигабайт;они не будут существовать, если браузеры запретят эти загрузки для начала.

То, что вы показали выше, является правильным использованием FormData для загрузки файлов с поддержкой AJAX.

Для ASPДля приложений .NET вам также может понадобиться настроить атрибут maxRequestLength узла <httpRuntime> в файле web.config.Обратите внимание, что это значение указывается в килобайт , в то время как maxAllowedContentLength указывается в байт .

Все вместе, чтобы разрешить загрузку файлов до 20 МБ, вы должны иметьэти параметры в файле web.config:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.web>
    <!-- 20 MB specified in kilobytes -->
    <httpRuntime maxRequestLength="20480" />
  </system.web>
  <system.webServer>
    <security>
      <requestFiltering>
        <!-- maxAllowedContentLength is in bytes (B)  -->
        <requestLimits maxAllowedContentLength="20971520"/>
        <!-- 20MB -->
      </requestFiltering>
    </security>
  </system.webServer>
</configuration>

Чтобы улучшить взаимодействие с пользователем, вы можете проверить размер файла до начала загрузки, просмотрев свойство file.size:

var file = $('#eval-attachment-modal-file')[0].files[0];
if (file && file.size <= 20971520) {
    // proceed with upload
} else {
    // file too large, show error
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...