ASP.NET MVC长耗时请求无法触发Ajax回调的IIS配置咨询
Hey there! Let's figure out why that one IIS server is dropping your long-running requests before they hit your Ajax .done() callback. Since the other two servers work perfectly, it’s definitely a configuration mismatch—here are the key settings to check first:
1. IIS Site Connection Timeout
First up, check the connection timeout for the problematic site in IIS:
- Open IIS Manager, right-click your site → Advanced Settings
- Look for the Connection Timeout value (default is 120 seconds)
- If your long-running operation exceeds this time, IIS will forcibly drop the connection, which means your client never gets a complete response to trigger
.done(). Bump this up to a value that covers your operation’s maximum runtime (e.g., 300 seconds for 5 minutes).
2. ASP.NET Execution Timeout
For traditional ASP.NET (not Core), the executionTimeout in your web.config controls how long ASP.NET will let a request run before terminating it:
- Open your application’s
web.configand find the<httpRuntime>node - Add or update the
executionTimeoutattribute (default is 110 seconds):<httpRuntime executionTimeout="300" maxRequestLength="1048576" /> - Important: This setting only works when
debug="false"in your<compilation>node—debug mode disables timeout checks.
3. Application Pool Idle & Recycling Settings
Your application pool might be recycling mid-request:
- In IIS Manager, go to Application Pools → right-click your app pool → Advanced Settings
- Check Idle Time-out (minutes) (default is 20): If your request runs longer than this, the pool will shut down idle processes, killing your request. Set it to a higher value or
0(never time out) for testing. - Also look at Recycling rules: If the pool is set to recycle at fixed intervals (e.g., every 1740 minutes), make sure your long requests don’t line up with that schedule. Temporarily disable fixed interval recycling to rule this out.
4. Response Buffering
IIS buffers responses by default, meaning it holds the entire response until the request finishes before sending it to the client. For extra-long requests, this can sometimes lead to unexpected drops. Try disabling buffering:
- In your controller action, add this line early in the code:
Response.BufferOutput = false; - Or add this to your
web.configto disable it server-wide for the app:<system.webServer> <httpProtocol> <customHeaders> <add name="X-Accel-Buffering" value="no" /> </customHeaders> </httpProtocol> </system.webServer>
5. Firewall/Load Balancer Timeouts
If this server sits behind a firewall or load balancer, those devices often have their own connection timeout rules that might be shorter than IIS’s settings. For example, many firewalls default to a 300-second timeout. Check those devices’ configurations and extend the timeout to match or exceed your IIS/ASP.NET settings.
6. Quick Client-Side Check
While the other servers work, double-check your Ajax call’s timeout setting to rule out a client-side issue. In jQuery, make sure the timeout value is long enough, and add a .fail() handler to debug errors:
$.ajax({ url: '/YourController/YourLongRunningAction', timeout: 600000, // 10 minutes (adjust as needed) type: 'POST', // ... other settings }).done(function(result) { // Your success logic }).fail(function(xhr) { // Debug: see what error you're getting console.log(xhr.status, xhr.statusText); });
This will help you identify if you’re getting a 504 (gateway timeout), 500 (server error), or 408 (request timeout)—clues that point directly to the root cause.
Pro Tip
Since you have two working servers, compare their IIS and web.config settings to the problematic one. The difference is almost certainly in one of the areas above. Start with the execution timeout and IIS connection timeout—those are the most common culprits for this exact issue.
内容的提问来源于stack exchange,提问作者user3367824

