使用Dart的http/dio包请求RSS链接遇解析错误:115≠13
问题:Dart请求Popular Mechanics RSS接口解析失败,错误"115 does not match 13"
尝试请求URL https://www.popularmechanics.com/rss/science/?src=rss,浏览器访问正常,但用Dart的http包或dio包发送请求时,均抛出解析异常:ClientException: Failed to parse HTTP, 115 does not match 13, uri=https://popularmechanics.com/rss/science/?src=rss
复现代码及报错
使用http包的代码
import 'package:http/http.dart' as http; void main() { final client = http.Client(); final Uri url = Uri.https('popularmechanics.com', '/rss/science/', { 'src': 'rss' }); try { client.get(url); } catch (e) { print(e); } }
报错信息
Unhandled exception: ClientException: Failed to parse HTTP, 115 does not match 13, uri=https://popularmechanics.com/rss/science/?src=rss #0 IOClient.send (package:http/src/io_client.dart:121:7) <asynchronous suspension> #1 BaseClient._sendUnstreamed (package:http/src/base_client.dart:93:32) <asynchronous suspension> Process finished with exit code 255
使用dio包的代码
import 'package:dio/dio.dart'; void main() { final client = Dio(); try { client.get('https://popularmechanics.com/rss/science/', queryParameters: { 'src': 'rss' }); } catch (e) { print(e); } }
报错信息
Unhandled exception: DioException [unknown]: null Error: HttpException: Failed to parse HTTP, 115 does not match 13, uri = https://popularmechanics.com/rss/science/?src=rss #0 DioMixin.fetch.<anonymous closure> (package:dio/src/dio_mixin.dart:507:7) #1 _FutureListener.handleError (dart:async/future_impl.dart:180:22) #2 Future._propagateToListeners.handleError (dart:async/future_impl.dart:858:47) #3 Future._propagateToListeners (dart:async/future_impl.dart:879:13) #4 Future._completeError (dart:async/future_impl.dart:655:5) #5 _SyncCompleter._completeError (dart:async/future_impl.dart:63:12) #6 _Completer.completeError (dart:async/future_impl.dart:27:5) #7 Future.any.onError (dart:async/future.dart:618:45) #8 _RootZone.runBinary (dart:async/zone.dart:1666:54) #9 _FutureListener.handleError (dart:async/future_impl.dart:177:22) #10 Future._propagateToListeners.handleError (dart:async/future_impl.dart:858:47) #11 Future._propagateToListeners (dart:async/future_impl.dart:879:13) #12 Future._completeError (dart:async/future_impl.dart:655:5) #13 Future._asyncCompleteError.<anonymous closure> (dart:async/future_impl.dart:745:7) #14 _microtaskLoop (dart:async/schedule_microtask.dart:40:21) #15 _startMicrotaskLoop (dart:async/schedule_microtask.dart:49:5) #16 _runPendingImmediateCallback (dart:isolate-patch/isolate_patch.dart:118:13) #17 _Timer._runTimers (dart:isolate-patch/timer_impl.dart:405:11) #18 _Timer._handleMessage (dart:isolate-patch/timer_impl.dart:429:5) #19 _RawReceivePort._handleMessage (dart:isolate-patch/isolate_patch.dart:184:12) Process finished with exit code 255
错误代码含义
- 13:是ASCII中的回车符(CR,
\r)的十进制值。HTTP协议要求响应头结束后,必须以\r\n\r\n作为响应头与响应体的分隔符,解析器在这里期望找到回车符。 - 115:是ASCII中的字母
s的十进制值。说明Dart的HTTP解析器在预期回车符的位置,收到了字符s,导致协议解析失败。
这种情况大多是因为服务器检测到请求来自非浏览器客户端(缺少必要请求头),返回了不符合标准HTTP协议的响应内容。
解决方案
核心修复:添加User-Agent请求头
模拟浏览器的请求头,让服务器返回标准HTTP响应:
修复后的http包代码
import 'package:http/http.dart' as http; void main() async { final client = http.Client(); final Uri url = Uri.https('popularmechanics.com', '/rss/science/', { 'src': 'rss' }); try { final response = await client.get( url, headers: { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36' }, ); print(response.body); } catch (e) { print(e); } finally { client.close(); } }
修复后的dio包代码
import 'package:dio/dio.dart'; void main() async { final client = Dio(); try { final response = await client.get( 'https://popularmechanics.com/rss/science/', queryParameters: {'src': 'rss'}, options: Options( headers: { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36' }, ), ); print(response.data); } catch (e) { print(e); } finally { client.close(); } }
额外注意点
原代码未使用await处理异步请求,导致异常无法被当前代码块捕获(异步任务的异常会在全局抛出)。修复代码中已添加async/await,并确保客户端资源被正确关闭。
内容的提问来源于stack exchange,提问作者TijnvdEijnde
相关产品推荐
相关产品推荐

