通过 AJAX POST 请求(IIS 7、ASP.NET MVC 4)向服务器传递大文件时出错

Posted

技术标签:

【中文标题】通过 AJAX POST 请求(IIS 7、ASP.NET MVC 4)向服务器传递大文件时出错【英文标题】:Error When Passing Large Files to Server via AJAX POST Request (IIS 7, ASP.NET MVC 4) 【发布时间】:2020-01-26 04:47:20 【问题描述】:

这是我在 *** 上的第一篇文章,所以如果我的问题采用非常规格式,我提前道歉。我在 Intranet 站点上有一个表单,它允许用户通过将文件传递到服务器来上传文件。将文件传递到服务器的 js 函数如下所示。此代码在较小的文件(最大为 900kb)上运行完美,但较大的文件 (9mb) 会产生 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 有时会在尝试将大文件传递到服务器时与您发生冲突,因此我将这个建议的代码添加到我的 Web 配置中无济于事

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

我怀疑这是 IIS 搞砸了我,但坦率地说,我没有想法。请告知 SO 社区

【问题讨论】:

您是否在 IIS 管理器中安装了该服务? 是的,但是请求永远不会到达服务器,这意味着服务永远不会参与错误。我可能应该从问题中删除那一点 【参考方案1】:

通常,您不受客户端文件大小的限制,而几乎总是在服务器端。 IIS 中的默认值相当低,以防止人们上传导致服务器空间不足的文件。例如,考虑允许人们上传数 GB 视频文件的服务;如果浏览器阻止这些上传开始,它们就不会存在。

您在上面显示的是正确使用FormData 来执行启用 AJAX 的文件上传。

对于 ASP.NET 应用程序,您可能还需要在 web.config 中配置 &lt;httpRuntime&gt; 节点的 maxRequestLength 属性。请注意,此值以 千字节 为单位指定,而 maxAllowedContentLength字节 为单位指定。

总而言之,要允许上传最大 20MB 的文件,您应该在 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

【讨论】:

以上是关于通过 AJAX POST 请求(IIS 7、ASP.NET MVC 4)向服务器传递大文件时出错的主要内容,如果未能解决你的问题,请参考以下文章

asp.net 发布到IIS后,Get提交会出现413错误,请求内容过大,不想改成post提交,请问该怎么解决

来自 ASP NET Web API 的 CORS 阻止 Ajax POST 调用 - 对预检请求的响应未通过访问控制检查

通过服务器端设置解决前端AJAX请求跨域访问WebServie(C#开发,IIS发布)

求助。asp.net 比较GET和POST传值方法

如何配置 IIS,使我在同一台机器上运行的 ASP.NET Web 应用程序可以互相 POST,但公众不能 POST?

如何配置 IIS 7.5 以使用“POST”方法接受对 .json 文件的请求