Dart用Dio请求网易云音乐接口返回200但response.data为null
解决Dart Dio请求网易云音乐接口返回200但data为null的问题
1. 开启响应解压并配置正确的解析类型
网易云接口返回的响应默认是gzip压缩格式,Dio如果未开启自动解压会导致解析失败,返回null。同时要确保设置响应类型为JSON。
import 'dart:convert'; import 'dart:io'; import 'package:dio/dio.dart'; void main() async { Dio dio = Dio(); // 配置基础选项 dio.options = BaseOptions( responseType: ResponseType.json, headers: {'Accept-Encoding': 'gzip, deflate'}, ); // 添加拦截器处理gzip解压 dio.interceptors.add(InterceptorsWrapper( onResponse: (response, handler) { if (response.headers['content-encoding']?.contains('gzip') == true) { final decodedBytes = GZipCodec().decode(response.data); response.data = json.decode(utf8.decode(decodedBytes)); } handler.next(response); }, )); // 后续请求逻辑... }
2. 完全对齐Postwoman的请求头
网易云接口对请求头校验严格,需复制Postwoman中使用的所有请求头(尤其是User-Agent、Referer、Content-Type):
dio.options.headers.addAll({ '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', 'Referer': 'https://music.163.com/', 'Content-Type': 'application/x-www-form-urlencoded', });
3. 按要求传递加密后的参数
网易云weapi接口要求参数以application/x-www-form-urlencoded格式传输,需将加密后的params和encSecKey封装为表单数据:
// 假设已完成weapi加密,得到以下两个参数 String encryptedParams = 'xxx'; String encSecKey = 'xxx'; // 方式1:使用FormData FormData formData = FormData.fromMap({ 'params': encryptedParams, 'encSecKey': encSecKey, }); // 方式2:直接传递编码后的字符串 // String postData = 'params=$encryptedParams&encSecKey=$encSecKey'; Response response = await dio.post( 'https://music.163.com/weapi/personalized/playlist', data: formData, // 或postData ); print(response.data); // 此时应能正常获取数据
4. 排查拦截器冲突
如果之前配置了自定义拦截器,可能会篡改或清空响应数据。可暂时移除所有非必要拦截器,测试是否能正常返回结果:
// 清空所有拦截器,只保留必要的解压逻辑 dio.interceptors.clear(); dio.interceptors.add(InterceptorsWrapper( onResponse: (response, handler) { // 解压逻辑... handler.next(response); }, ));
内容的提问来源于stack exchange,提问作者MYB
相关产品推荐
相关产品推荐

