Note-31132-14

Token ID: 1

ERC-721 1 Transfers

Metadata

{
  "title": "一个 Flutter 依赖的修补踩坑记录",
  "tags": [
    "post",
    "踩坑",
    "记录",
    "前端",
    "编程"
  ],
  "summary": "又一次毛毛雨一样的踩坑记录",
  "sources": [
    "xlog"
  ],
  "external_urls": [
    "https://zsakvo.xlog.app/webdav-pub-fix"
  ],
  "date_published": "2023-04-08T14:55:56.506Z",
  "content": "最近在给自己的[二步验证项目](https://github.com/zsakvo/Kakunin-Mobile)开发基于 webdav 的备份功能,按套路,自然是先去 pub 仓库搜索相关的包。然后就顺利地发现了这么个东西:[webdav_client](https://pub.dev/packages/webdav_client)。\n\n---\n\n可是在实际使用时,发现虽然可以顺利备份文件,但是在恢复的时候却爆出了读取错误。\n\n```\nI/flutter ( 9654): Response Text:\nI/flutter ( 9654): [60, 97, 32, 104, 114, 101, 102, 61, 34, 104, 116, 116, 112, 115, 58, 47, 47, 99, 110, 45, 98, 101, 105, 106, 105, 110, 103, 45, 100, 97, 116, 97, 46, 97, 108\nI/flutter ( 9654):\nI/flutter ( 9654):   ERROR ┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────\nI/flutter ( 9654):   ERROR │ #0   Log.e (package:kakunin/utils/log.dart:22:13)\nlog.dart:22\nI/flutter ( 9654):   ERROR │ #1   CloudAccountNotifier.restoreWebDav (package:kakunin/provider.dart:304:11)\nprovider.dart:304\nI/flutter ( 9654):   ERROR ├┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄\nI/flutter ( 9654):   ERROR │ ⛔ DioError [bad response]: null\nI/flutter ( 9654):   ERROR │ ⛔ Error: Found\nI/flutter ( 9654):   ERROR └───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────\n```\n\n首先,我连接的 webdav 是在局域网的树莓派上,通过 Alist 转发的阿里云盘。粗略看了下,既然日志显示已经打印了 `Response Text` 的数组,最后却报错为空,那估计应该是作者没能正确处理状态码为 3xx 时转发的情况,而直接抛出了错误。\n\n那么思路就很清晰了:\n\n克隆其源代码,运行 example,根据抛错很容易定位到文件 `lib/src/webdav_dio.dart`,可见有如此内容:\n\n```dart\nif (resp.statusCode != 200) {\n      throw newResponseError(resp);\n}\n```\n果然,只要不是 200 就抛错了,没有进一步处理。\n\n那处理起来也是很简单的,只要针对 3XX 的情况做一些额外判断即可,追加如下内容:\n\n```dart\nif (resp.statusCode! >= 300 && resp.statusCode! < 400) {\n    return (await this.req(\n        self,\n        'GET',\n        resp.headers[\"location\"]!.first,  // 获取到重定向的正确地址,再次请求一遍\n        optionsHandler: (options) =>\n        options.responseType = ResponseType.bytes,\n        onReceiveProgress: onProgress,\n        cancelToken: cancelToken,\n    )).data;\n}\n```\n\n然后发现在请求时被强行拼接了原本的 host,导致依旧出错。再次修正 `req` 方法内的请求地址即可:\n\n```dart\nvar resp = await this.requestUri<T>(\n      Uri.parse(\n          '${path.startsWith(RegExp(r'(http|https)://')) ? path : join(self.uri, path)}'),\n      options: options,\n      data: data,\n      onSendProgress: onSendProgress,\n      onReceiveProgress: onReceiveProgress,\n      cancelToken: cancelToken,\n);\n```\n\n此时经过测试,已经可以读取到 Alist 转发的阿里云盘内容。\n\n---\n\n总的来说,问题不大,稍有糟心而已。",
  "attributes": [
    {
      "value": "webdav-pub-fix",
      "trait_type": "xlog_slug"
    }
  ]
}