SignalR跨域连接协商请求报错:返回200仍提示Error during negotiation request
Hey there, let's dig into why your SignalR cross-domain connection is throwing that negotiation error even though the initial request returns 200. I'll walk through the most likely issues based on your code and the response you shared:
1. Mismatched SignalR Versions
First up, check if your server-side SignalR NuGet packages match the client-side JS version (2.2.3). Version mismatches are a super common culprit here—even if the negotiation request returns 200, the client and server might speak slightly different "languages" during the handshake, leading to a failed negotiation.
- Open your NuGet Package Manager and verify versions for
Microsoft.AspNet.SignalR.Core,Microsoft.AspNet.SignalR.Owin, andMicrosoft.AspNet.SignalR.Js(if installed) are all 2.2.3, matching your client'sjquery.signalR-2.2.3.min.js.
2. Incorrect Negotiation Response Format
Looking at the response content you shared, it's formatted as plain key-value text (like form data), but SignalR expects a JSON response for negotiation. This is a big red flag—your client is trying to parse JSON but gets plain text, hence the error even with a 200 status.
Possible fixes:
- Check if there's any middleware in your OWIN pipeline (outside the
/signalrbranch) that's modifying response formats. For example, if you have WebApi middleware with custom formatters, or a middleware that forces form-urlencoded responses, it might be interfering with SignalR's output. - Ensure your
HubConfigurationisn't overriding default formatting settings. The default setup should return JSON, so avoid any custom formatter changes unless absolutely necessary.
3. CORS Configuration Checks
Your server-side CORS setup looks correct on the surface (map.UseCors(CorsOptions.AllowAll) before SignalR), but let's verify a few details:
- Confirm that the
OPTIONSpreflight request (check your browser's Network tab) returns 200. SignalR relies on preflight requests for cross-domain connections, and a missing or invalid preflight response can break negotiation even if the main request succeeds. - If your client needs to send credentials (like cookies), make sure to enable
withCredentialson the client side:
And ensure your server's CORS policy allows credentials (thoughconnection.start({ withCredentials: true })CorsOptions.AllowAllshould include this, but it's worth double-checking).
4. Client Connection Tweaks
Your client code has a minor quirk—you're creating a hub connection first, then setting the URL. Try creating the connection with the URL directly to avoid any potential path issues:
$(document).ready(function () { // Pass the SignalR URL directly when creating the connection var connection = $.hubConnection('http://localhost:64585/signalr'); var contosoChatHubProxy = connection.createHubProxy('Chat'); connection.start({ withCredentials: true }) .done(function () { console.log('Now connected, connection ID=' + connection.id); }).fail(function (e) { console.error('Could not connect: ', e); }); });
5. Verify Startup Class Registration
Make sure your Startup1 class is actually being loaded by OWIN. Add the OwinStartup attribute to your assembly if you haven't already:
[assembly: OwinStartup(typeof(YourProjectNamespace.Startup1))]
Without this, OWIN might not use your custom startup configuration, leading to unexpected behavior.
Quick Debugging Tip
Open your browser's DevTools Network tab, filter for XHR requests, and look at the /signalr/negotiate request:
- Check the
Content-Typeresponse header—it should beapplication/json. - Inspect the response body to confirm it's valid JSON (not the plain text you shared earlier).
Start with the version mismatch and response format checks first—those are the most likely fixes here.
内容的提问来源于stack exchange,提问作者patricia

