如何设置一个基本 URL 以及在哪里为 api 调用在颤振 dio 中声明它?

Posted

技术标签:

【中文标题】如何设置一个基本 URL 以及在哪里为 api 调用在颤振 dio 中声明它?【英文标题】:How to setup a base URL and where do I declare it in flutter dio for api calls? 【发布时间】:2020-12-07 10:22:20 【问题描述】:

比如如何在单独的文件中修复样板代码并在 ui 页面中使用它。

我需要在单独的文件中声明这个 uri 变量并跨所有页面访问:

  static var uri = "https://xxx/xxx/web_api/public";
  static BaseOptions options = BaseOptions(
  baseUrl: uri,
  responseType: ResponseType.plain,
  connectTimeout: 30000,
  receiveTimeout: 30000,
  // ignore: missing_return
  validateStatus: (code) 
    if (code >= 200) 
      return true;
    
  );  static Dio dio = Dio(options);

在 UI 页面中,我必须在未来的函数中声明 uri 变量和 BaseOption 变量:

   Future<dynamic> _loginUser(String email, String password) async 
     try 
  Options options = Options(
    headers: "Content-Type": "application/json",
  );
  Response response = await dio.post('/login',
      data: 
        "email": email,
        "password": password,
        "user_type": 2,
        "status": 1
      ,
      options: options);

  if (response.statusCode == 200 || response.statusCode == 201) 
    var responseJson = json.decode(response.data);
    return responseJson;
   else if (response.statusCode == 401) 
    throw Exception("Incorrect Email/Password");
   else
    throw Exception('Authentication Error');
 on DioError catch (exception) 
  if (exception == null ||
      exception.toString().contains('SocketException')) 
    throw Exception("Network Error");
   else if (exception.type == DioErrorType.RECEIVE_TIMEOUT ||
      exception.type == DioErrorType.CONNECT_TIMEOUT) 
    throw Exception(
        "Could'nt connect, please ensure you have a stable network.");
   else 
    return null;
  

【问题讨论】:

不清楚是什么问题。基本 url 似乎设置正确baseUrl: uri,。然后,您可以使用 FutureBuilder 小部件在将其公开(假设它在不同的文件中)后使用 _loginUser,方法是将其重命名为 loginUser 基本 url 样板代码需要在单独的页面中,而不是在同一页面中,并且从使用 apis:like 的所有页面传递的该类 uri 和选项变量中 Response response = await dio.post('Uri+/login', data: "email": email, "password": password, "user_type": 2, "status": 1 ,选项:选项);@Er1 link 如果对您有用,请接受以下答案。所以,我们可以节省其他人的时间 :) @SanjeeviRaj 【参考方案1】:

您可以创建 app_config.dart 文件并管理不同的环境,如下所示:

const _baseUrl = "baseUrl";

enum Environment  dev, stage, prod 

Map<String, dynamic> _config;

void setEnvironment(Environment env) 
  switch (env) 
    case Environment.dev:
      _config = devConstants;
      break;
    case Environment.stage:
      _config = stageConstants;
      break;
    case Environment.prod:
      _config = prodConstants;
      break;
  


dynamic get apiBaseUrl 
  return _config[_baseUrl];


Map<String, dynamic> devConstants = 
  _baseUrl: "https://devapi.xyz.com/",
;


Map<String, dynamic> stageConstants = 
  _baseUrl: "https://api.stage.com/",
;

Map<String, dynamic> prodConstants = 
  _baseUrl: "https://api.production.com/",
;

【讨论】:

如何调用 setEnvironment? @WilliamChou 我们有 3 个环境:开发、阶段、生产。我们有 3 个 dart 文件,它们根据风格设置当前环境。 1) main_dev.dart,2) main_stage.dart,3) main_prod.dart。因此,根据选择的风味,我们将在 dart 文件中设置环境。 @WilliamChou 如果您需要任何帮助,请告诉我。【参考方案2】:

也许不是静态地声明你的Dio对象,你可以把它放在一个类中,也把你的loginUser函数放在那里,然后使用Provider来获取那个对象,以便在你需要的地方调用它。

class Api 
  static var uri = "https://xxx/xxx/web_api/public";
  static BaseOptions options = BaseOptions(
  baseUrl: uri,
  responseType: ResponseType.plain,
  connectTimeout: 30000,
  receiveTimeout: 30000,
  // ignore: missing_return
  validateStatus: (code) 
    if (code >= 200) 
      return true;
    
  ); 
  Dio dio = Dio(options);

  Future<dynamic> loginUser(String email, String password) async 
    try 
      RequestOptions options = RequestOptions(
        headers: "Content-Type": "application/json",
      );
    Response response = await dio.post('/login',
        data: 
          "email": email,
          "password": password,
          "user_type": 2,
          "status": 1
        ,
        options: options);
    //the rest of your code here

https://pub.dev/packages/provider

Provider(
  create: (_) => Api(),
  child: ...
)

https://api.flutter.dev/flutter/widgets/FutureBuilder-class.html

YourWidget(
  child: Consumer<Api>(
    builder: (context, api, child) 
      return FutureBuilder<dynamic>(
      future: api.loginUser('mail@mail.com', 'user_password')
      builder: (BuildContext context, AsyncSnapshot<dynamic> snapshot) 
        if (snapshot.hasData) 
          //show a widget based on snapshot.data
         else 
          //show another widget
        
      
    ,
  ),
)

【讨论】:

谢谢@Er1

以上是关于如何设置一个基本 URL 以及在哪里为 api 调用在颤振 dio 中声明它?的主要内容,如果未能解决你的问题,请参考以下文章

如何在 JQuery 中格式化 URL.Action() 调用以设置链接的 href 属性?

如何使用颤振 http 包设置基本 url 类?

Auth0 回调 URL 不匹配以及我们在哪里设置回调 URL

在哪里进行 API 调用以及如何构建操作

如何错开异步 API 调用以防止使用 grequests 库进行最大重试?

如何仅针对特定 url 添加 Spring Security 验证码过滤器