使用Dart/Flutter的http.get访问本地IP返回400状态码问题排查
Let’s walk through the most likely fixes for your issue—since your API works with curl and browsers but fails in Dart/Flutter, the problem is almost certainly tied to request formatting or platform-specific network rules.
1. Fix the Request Header (Top Cause for 400 Status)
Your code uses a header key content instead of the standard Content-Type. Most REST APIs strictly validate header names, and sending an invalid header can trigger a 400 Bad Request.
Even better: GET requests rarely need a Content-Type header (since they don’t include a request body). Try removing it entirely, or use the correct key if you do need it:
// Option 1: No Content-Type header for GET (preferred) http.Response response1 = await http.get(url); // Option 2: Correct header key if required by the API http.Response response1 = await http.get(url, headers: {"Content-Type": "application/json"});
2. Match the Exact URL Path (Trailing Slash Mismatch)
I noticed your HttpClient call uses a trailing slash (/api/device/state/) while your http.get call doesn’t (/api/device/state). Many web servers treat these as distinct endpoints, which could explain the 400.
Make sure your Dart/Flutter code uses the exact same path as your working curl command. For example, if curl uses http://192.168.0.5/api/device/state (no slash), update all your Dart requests to match that.
3. Fix Flutter’s Platform-Specific Network Restrictions (SocketException)
The No route to host error is usually a permission or security policy issue on mobile:
Android
- Add internet permission to
android/app/src/main/AndroidManifest.xml:<uses-permission android:name="android.permission.INTERNET" /> - For Android 9+ (API 28+), cleartext HTTP (non-HTTPS) is blocked by default. Enable it by adding this to the
<application>tag:android:usesCleartextTraffic="true"
iOS
- Allow HTTP requests to your local device in
ios/Runner/Info.plist. Add this section:
This is more secure than allowing all arbitrary loads, as it only permits HTTP traffic to your specific local IP.<key>NSAppTransportSecurity</key> <dict> <key>NSExceptionDomains</key> <dict> <key>192.168.0.5</key> <dict> <key>NSIncludesSubdomains</key> <true/> <key>NSTemporaryExceptionAllowsInsecureHTTPLoads</key> <true/> </dict> </dict> </dict>
4. Mirror curl’s Request Headers Exactly
Use curl -v http://192.168.0.5/api/device/state to see every header curl sends (look for lines starting with >). Then replicate those headers in your Dart code—some APIs reject requests with unusual User-Agent values or missing Accept headers.
Example of matching curl’s headers:
http.Response response = await http.get( url, headers: { "Accept": "*/*", "User-Agent": "curl/7.81.0", // Use your curl's User-Agent from the -v output }, );
5. Debug HttpClient with Proper Configuration
Your current HttpClient code doesn’t set any headers, which might be causing issues. Try adding headers and logging more details:
HttpClient client = HttpClient(); client.getUrl(Uri.parse('http://192.168.0.5/api/device/state')) .then((request) { // Add headers matching curl's output request.headers.set('Accept', '*/*'); return request.close(); }) .then((response) { print('Status Code: ${response.statusCode}'); print('Reason Phrase: ${response.reasonPhrase}'); response.transform(Utf8Decoder()).listen((body) => print('Body: $body')); }) .catchError((error) => print('Error: $error'));
Start with fixing the header and URL path—those are the quickest wins. Then move to platform permissions if you’re still seeing socket errors.
内容的提问来源于stack exchange,提问作者Aleksander Żołądkiewicz

