颤振无法从 api 获取数据,dio 错误

Posted

技术标签:

【中文标题】颤振无法从 api 获取数据,dio 错误【英文标题】:flutter can't fetch data from api , dio error 【发布时间】:2021-12-16 14:15:14 【问题描述】:

所以我正在开发一个 NewsApp,我可以成功地获取数据并显示它,但是搜索功能不起作用! 昨天它只是坚持这个错误!我遇到了 SOF 和 git 的所有解决方案,但都以失败告终。 我在下面提供了每个相关代码的图像。请帮忙

基本网址:https://newsapi.org/ 方法:v2/top-headlines? 查询:country=us&category=business&apiKey=65f7f556ec76449fa7dc7c0069f040ca

用于搜索目的: https://newsapi.org/v2/everything?q=tesla&apiKey=65f7f556ec76449fa7dc7c0069f040ca

DioError [DioErrorType.other]:SocketException:主机查找失败: “newsapi.orgv2”(操作系统错误:没有与主机名关联的地址,errno = 7)

Here's the error

dio code

cubit code

main class

dio代码

class DioHelper 
  static late Dio dio;

  static init() 
    dio = Dio(
      BaseOptions(
        baseUrl: 'https://newsapi.org',
        receiveDataWhenStatusError: true,
      ),
    );
  

  static Future<Response> getData(
    required String url,
    required Map<String, dynamic> query,
  ) async 
    return await dio.get(
      url,
      queryParameters: query,
    );
  

肘码

class NewsCubit extends Cubit<NewsStates> 
  NewsCubit() : super(NewsInitialStates());

  static NewsCubit get(context) => BlocProvider.of(context);

  int currentindex = 0;
  List<BottomNavigationBarItem> bottomItems = [
    const BottomNavigationBarItem(
        icon: Icon(Icons.add_business_outlined), label: 'Business'),
    const BottomNavigationBarItem(
        icon: Icon(Icons.sports_football_outlined), label: 'Sports'),
    const BottomNavigationBarItem(
        icon: Icon(Icons.science_outlined), label: 'Science'),
  ];

  List<Widget> screens = [
    const BusinessScreen(),
    const SportsScreen(),
    ScienceScreen(),
  ];

  void changeBottomNavBar(int index) 
    currentindex = index;
    if (index == 1) getSports();
    if (index == 2) getScience();
    emit(NewsBottomNavState());
  

  List<dynamic> business = [];

  void getBusiness() 
    emit(NewsGetBusinessLoadingState());
    DioHelper.getData(
      url: '/v2/top-headlines',
      query: 
        'country': 'eg',
        'category': 'business',
        'apiKey': '65f7f556ec76449fa7dc7c0069f040ca',
      ,
    ).then((value) 
      // print(value.data['articles'][0]['title']);
      business = value.data['articles'];
      print(business[0]['title']);
      emit(NewsGetBusinessSuccessState());
    ).catchError((e) 
      print(e.toString());
      emit(NewsGetBusinessErrorState(e.toString()));
    );
  

  List<dynamic> sports = [];

  void getSports() //sports code just like business
  

  List<dynamic> science = [];

  void getScience() //science code just like business
  

  List<dynamic> search = [];

  void getSearch(String value) 
    emit(NewsGetSearchLoadingState());
    search = [];
    DioHelper.getData(
      url: '/v2/everything',
      query: 
        'q': '$value',
        'apiKey': '65f7f556ec76449fa7dc7c0069f040ca',
      ,
    ).then((value) 
      // print(value.data['articles'][0]['title']);
      search = value.data['articles'];
      print(search[0]['title']);
      emit(NewsGetSearchSuccessState());
    ).catchError((e) 
      print(e.toString());
      emit(NewsGetSearchErrorState(e.toString()));
    );
  

主类

void main() async 
  WidgetsFlutterBinding.ensureInitialized();

  Bloc.observer = MyBlocObserver();
  HttpOverrides.global = MyHttpOverrides();
  DioHelper.init();
  await CacheHelper.init();

  bool? isDark = CacheHelper.getBoolean(key: 'isDark');

  runApp(MyApp(isDark));


class MyApp extends StatelessWidget 
  bool? isDark;
  MyApp(this.isDark);
  @override
  Widget build(BuildContext context) 
    return MultiBlocProvider(
      providers: [
        BlocProvider(
          create: (context) => NewsCubit()
            ..getBusiness()
            ..getSports()
            ..getScience(),
        ),
        BlocProvider(
          create: (context) => AppCubit()
            ..ChangeAppMode(
              fromShared: isDark,
            ),
        )
      ],
      child: BlocConsumer<AppCubit, AppState>(
        listener: (context, state) ,
        builder: (context, state) 
          return MaterialApp(
            debugShowCheckedModeBanner: false,
            theme: ThemeData(
              primarySwatch: Colors.deepOrange,
              scaffoldBackgroundColor: Colors.white,
              floatingActionButtonTheme: const FloatingActionButtonThemeData(
                backgroundColor: Colors.deepOrangeAccent,
              ),
              appBarTheme: const AppBarTheme(
                titleSpacing: 20,
                iconTheme: IconThemeData(
                  color: Colors.black,
                ),
                // backwardsCompatibility: false,
                systemOverlayStyle: SystemUiOverlayStyle(
                  statusBarColor: Colors.white,
                  statusBarIconBrightness: Brightness.dark,
                ),
                backgroundColor: Colors.white,
                elevation: 0.0,
                titleTextStyle: TextStyle(
                  color: Colors.black,
                  fontSize: 20,
                  fontWeight: FontWeight.bold,
                ),
              ),
              bottomNavigationBarTheme: const BottomNavigationBarThemeData(
                type: BottomNavigationBarType.fixed,
                selectedItemColor: Colors.deepOrangeAccent,
                unselectedItemColor: Colors.grey,
                elevation: 50,
                backgroundColor: Colors.white,
              ),
              textTheme: const TextTheme(
                bodyText1: TextStyle(
                  fontSize: 18,
                  fontWeight: FontWeight.bold,
                  color: Colors.black,
                ),
              ),
            ),
            darkTheme: ThemeData(
              scaffoldBackgroundColor: HexColor('333739'),
              primarySwatch: Colors.deepOrange,
              backgroundColor: Colors.white,
              floatingActionButtonTheme: const FloatingActionButtonThemeData(
                backgroundColor: Colors.deepOrangeAccent,
              ),
              appBarTheme: AppBarTheme(
                titleSpacing: 20,
                iconTheme: const IconThemeData(
                  color: Colors.white,
                ),
                // backwardsCompatibility: false,
                systemOverlayStyle: SystemUiOverlayStyle(
                  statusBarColor: HexColor('333739'),
                  statusBarIconBrightness: Brightness.light,
                ),
                backgroundColor: HexColor('333739'),
                elevation: 0.0,
                titleTextStyle: const TextStyle(
                  color: Colors.white,
                  fontSize: 20,
                  fontWeight: FontWeight.bold,
                ),
              ),
              bottomNavigationBarTheme: BottomNavigationBarThemeData(
                type: BottomNavigationBarType.fixed,
                selectedItemColor: Colors.deepOrangeAccent,
                unselectedItemColor: Colors.grey,
                elevation: 50,
                backgroundColor: HexColor('333739'),
              ),
              textTheme: const TextTheme(
                bodyText1: TextStyle(
                  fontSize: 18,
                  fontWeight: FontWeight.bold,
                  color: Colors.white,
                ),
              ),
            ),
            themeMode:
                AppCubit.get(context).isDark ? ThemeMode.dark : ThemeMode.light,
            home: Directionality(
              child: NewsLayout(),
              textDirection: TextDirection.ltr,
            ),
          );
        ,
      ),
    );
  


class MyHttpOverrides extends HttpOverrides 
  @override
  HttpClient createHttpClient(SecurityContext? context) 
    return super.createHttpClient(context)
      ..badCertificateCallback =
          (X509Certificate cert, String host, int port) => true;
  

【问题讨论】:

不要发布您的代码图片,请发布代码本身。 您需要在路径名前加上/,例如/v2/... 请提供足够的代码,以便其他人更好地理解或重现问题。 我在路径之前添加了 / 但仍然给出错误“DioError [DioErrorType.response]: Http status error [429]” 我将立即用代码而不是图像来更新我的问题 HTTP 状态 429 表示请求过多。通常这是基于用户等的速率限制,所以也许你应该从问题中删除你的 API 密钥和/或重新生成一个新的。 【参考方案1】:

我想通了>刚刚在我的 Dio(baseoptions) 中添加了 connectTimeout、receiveTimeout,它对我有用!

class DioHelper 
  static late Dio dio;
  static init() 
    BaseOptions options = BaseOptions(
      baseUrl: baseUrl,
      connectTimeout: 20 * 1000,
      receiveTimeout: 20 * 1000,
      receiveDataWhenStatusError: true,
    );
    dio = Dio(options);
  

  static Future<List<dynamic>> getData(
      required Map<String, dynamic> query) async 
    try 
      Response response =
          await dio.get('v2/top-headlines', queryParameters: query);
      return response.data['articles'];
     catch (e) 
      print(e.toString());
      return [];
    
  

【讨论】:

【参考方案2】:

尝试将 / 放在你的 baseUrl 中的 org 之后

【讨论】:

你能提供一个你的解决方案的例子吗? 之前试过了,没关系....我发布了我的问题的答案,谢谢你的参与!

以上是关于颤振无法从 api 获取数据,dio 错误的主要内容,如果未能解决你的问题,请参考以下文章

无法从 api 获取数据,Future 总是返回 null - 颤振

无法从 API 获取图像

从json颤振中获取数组

从 php api 获取数据并填充颤振表

我的颤振应用程序没有从 release.apk 中的 api 获取数据,但在调试模式下工作

如何通过颤振从 api 中获取价值