【Flutter_Web】Flutter编译Web第三篇(网络请求篇):dio如何改造方法,变成web之后数据如何处理

前言

Flutter端在处理网络请求的时候,最常用的库当然是Dio了,那么在改造成web端的时候,最先处理的必然是网络请求,否则没有数据去处理驱动实图渲染。

官方链接

  • pub
https://pub.dev/packages/dio
  • github
https://github.com/cfug/dio/blob/main/dio/README-ZH.md

适配器问题

这里根据官网的指引去看web相关的配置,发现只需要更改适配器HttpClientAdapter即可,放出官方的截图:
在这里插入图片描述
然后我想说,这就是一个坑!!!,配置上去运行起来是不可用的。但是我们后面再说这个问题。

我们为了兼容多平台运行,必须使用条件编译的方式进行引入:

这里我建立了三个文件:
ai_network_mobile_adapter.dart作为移动端的适配器移动端是支持代理的

import 'package:dio/dio.dart';
import 'package:dio/io.dart';HttpClientAdapter getAdapter() {return IOHttpClientAdapter(// createHttpClient: () {//   final client = HttpClient();//   client.findProxy = (uri) {//     return 'PROXY 192.168.11.26:8888';//   };//   client.badCertificateCallback =//       (X509Certificate cert, String host, int port) => true; //忽略证书//   return client;// },);
}

ai_network_web_adapter.dart:web端适配器

import 'package:dio/browser.dart';
import 'package:dio/dio.dart';HttpClientAdapter getAdapter() {final adapter = HttpClientAdapter() as BrowserHttpClientAdapter;adapter.withCredentials = true;return adapter;
}

再通过条件编译文件去引入:

export 'ai_network_web_adapter.dart'if (dart.library.html) 'ai_network_web_adapter.dart'if (dart.library.io) 'ai_network_mobile_adapter.dart';

这样我们只需要使用getAdapter方法,条件编译会自动帮我们选中不同端的适配器。

这里不能用官网的方式去写,一定要这么写,这样才有效:

HttpClientAdapter getAdapter() {final adapter = HttpClientAdapter() as BrowserHttpClientAdapter;adapter.withCredentials = true;return adapter;
}

请求加解密

在移动端为了安全,必然会有请求上面的加解密,这里面涉及一些原生加解密和加解密相关的库文件,但在web端很多库不被支持,这里方式有很多,跟后端商量一下就可以,加特殊参数或者使用c的方式,这里不做过多赘述,不过也是时间问题和增加爆破成本。

跨域问题

跨域问题在浏览器环境是必然会出现的,特别是在本地调试的时候,这里我看了网上有很多种方案,大多都是做一层代理,可以使用浏览器插件,像我上一篇文章提到的插件,或者使用shelf_proxy

import 'dart:io';import 'package:shelf/shelf_io.dart' as shelf_io;
import 'package:shelf_proxy/shelf_proxy.dart';/// 命令 : dart ./lib/proxy_config.dart
void configServer(HttpServer server) {// 这里设置请求策略,允许所有server.defaultResponseHeaders.add('Access-Control-Allow-Origin', '*');server.defaultResponseHeaders.add('Access-Control-Allow-Credentials', true);server.defaultResponseHeaders.add('Access-Control-Allow-Methods', '*');server.defaultResponseHeaders.add('Access-Control-Allow-Headers', '*');server.defaultResponseHeaders.add('access-control-expose-headers', '*');print('Serving at http://${server.address.host}:${server.port}');
}Future<void> main() async {var reqHandle = proxyHandler("http://example.com/"); //要代理的域名/// 绑定本地端口,4500,转发到真正的服务器中var reqServer = await shelf_io.serve(reqHandle, 'localhost', 4500);configServer(reqServer);
}

开启一个代理服务器也可以。

不过还有一种简单的方式:
直接关闭浏览器的安全模式:

 "args": ["--target","lib/main.dart","--web-browser-flag","--disable-web-security","--web-renderer","html"],

当然最终上线还是要跟后端沟通好请求数据的要求。

预检请求或CORS问题

浏览器对于复杂请求会发出一个预检请求,也就是方法为OPTIONS的,这就是为什么在web端,同一个接口会触发两次的原因。

在这里插入图片描述
然后问题就来了,我的请求是Post,并且数据格式也是多表单数据,为什么还会发出OPTIONS请求呢,因为OPTIONS请求是先直接访问你的一级域名,然后不带任何数据去请求访问后端是否允许发送跨域请求的,这个时候正常都不会支持,因为明明可以直接发送数据,不需要多一次预检请求,发了反而失败了导致CORS,然后就不发送正常的请求了。

所以问题的关键在于,dio什么情况下会让你的请求变成复杂的请求?

这里我就去官方github仓库看了,发现不少人也提出了这样的问题,分享这一个问题吧:

https://github.com/cfug/dio/issues/2125

标题就是:Flutter web - simple request causing OPTIONS request

为什么简单的请求会发出OPTIONS 请求呢?

这位同学就说了:
在这里插入图片描述
如果你在web端,使用了connectTimeout / sendTimeout / onSendProgress这三个函数,在web端没有什么意义,反而会造成CORS,所以我在web端,单独对这三个方法做了null处理,结果确实是不会发送OPTIONS请求了。

我还没仔细去看这三个函数在源码中的实现,有时间会去研究一下,但是确实是解决了问题。

网络状态检测

之前在移动端可能会使用dio去做网络状态检测,能访问的通,就是有网络,这在web端是不可靠的,因为web端有跨域问题,访问其他域名大概率会失败,但失败不意味着你没有网络,因此可以使用web端原生的方法去检测网络。

结论

如果你有更多有趣的想法,欢迎在下方留言,我在查找很多关于flutter转web相关的内容,发现解决方案真的很少,很多都必须从官方仓库去获取,希望能给你带来一些帮助。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/64262.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring Boot @Conditional注解

在Spring Boot中&#xff0c;Conditional 注解用于条件性地注册bean。这意味着它可以根据某些条件来决定是否应该创建一个特定的bean。这个注解可以放在配置类或方法上&#xff0c;并且它会根据提供的一组条件来判断是否应该实例化对应的组件。 要使用 Conditional注解时&#…

项目上传到gitcode

首先需要在个人设置里面找到令牌 记住自己的账号和访问令牌&#xff08;一长串&#xff09;&#xff0c;后面git要输入这个&#xff0c; 账号是下面这个 来到自己的仓库 #查看远程仓库&#xff0c;是不是自己的云仓库 git remote -v # 创建新分支 git checkout -b llf # 三步…

【Rust自学】6.4. 简单的控制流-if let

喜欢的话别忘了点赞、收藏加关注哦&#xff0c;对接下来的教程有兴趣的可以关注专栏。谢谢喵&#xff01;(&#xff65;ω&#xff65;) 6.4.1. 什么是if let if let语法允许将if和let组合成一种不太冗长的方式来处理与一种模式匹配的值&#xff0c;同时忽略其余模式。 可以…

【Git学习】windows系统下git init后没有看到生成的.git文件夹

[问题] git init 命令后看不到.git文件夹 [原因] 文件夹设置隐藏 [解决办法] Win11 win10

vscode添加全局宏定义

利用vscode编辑代码时&#xff0c;设置了禁用非活动区域着色后&#xff0c;在一些编译脚本中配置的宏又识别不了 遇到#ifdef包住的代码就会变暗色&#xff0c;想查看代码不是很方便。如下图&#xff1a; 一 解决&#xff1a; 在vscode中添加全局宏定义。 二 步骤&#xff1a…

【服务器主板】定制化:基于Intel至强平台的全新解决方案

随着数据处理需求不断增长&#xff0c;服务器硬件的发展也在持续推进。在这一背景下&#xff0c;为用户定制了一款全新的基于Intel至强平台的服务器主板&#xff0c;旨在提供强大的计算能力、优异的内存支持以及高速存储扩展能力。适用于需要高性能计算、大规模数据处理和高可用…

php怎么去除数点后面的0

在PHP中&#xff0c;我们可以使用几种方法来去除数字小数点后的0。 方法一&#xff1a;使用intval函数 intval函数可以将一个数字转化为整数&#xff0c;另外&#xff0c;它也可以去除小数点后面的0。 “php $number 123.4500; $number intval($number); echo $number; // 输…

数字后端培训项目Floorplan常见问题系列专题续集1

今天继续给大家分享下数字IC后端设计实现floorplan阶段常见问题系列专题。这些问题都是来自于咱们社区IC后端训练营学员提问的问题库。目前这部分问题库已经积累了4年了&#xff0c;后面会陆续分享这方面的问题。 希望对大家的数字后端学习和工作有所帮助。 数字后端项目Floor…

【递归,搜索与回溯算法 综合练习】深入理解暴搜决策树:递归,搜索与回溯算法综合小专题(二)

优美的排列 题目解析 算法原理 解法 &#xff1a;暴搜 决策树 红色剪枝&#xff1a;用于剪去该节点的值在对应分支中&#xff0c;已经被使用的情况&#xff0c;可以定义一个 check[ ] 紫色剪枝&#xff1a;perm[i] 不能够被 i 整除&#xff0c;i 不能够被 per…

Java中各种数组复制方式的效率对比

在 Java 中&#xff0c;数组复制是一个常见的操作&#xff0c;尤其是在处理动态数组&#xff08;如 ArrayList&#xff09;时。Java 提供了多种数组复制的方式&#xff0c;每种方式在性能和使用场景上都有所不同。以下是对几种主要数组复制方式的比较&#xff0c;包括 System.a…

视频会议是如何实现屏幕标注功能的?

现在主流的视频会议软件都有屏幕标注功能&#xff0c;屏幕标注功能给屏幕分享者讲解分享内容时提供了极大的方便。那我们以傲瑞视频会议&#xff08;OrayMeeting&#xff09;为例&#xff0c;来讲解屏幕标注是如何实现的。 傲瑞会议的PC端&#xff08;Windows、信创Linux、银河…

Framework开发入门(一)之源码下载

一、使用Linux操作系统的小伙伴可以跳转到官网链接按提示操作 官网源码地址&#xff1a;下载源代码 | Android Open Source Project 1.创建一个空目录来存放您的工作文件。为其指定一个您喜欢的任意名称&#xff1a; mkdir WORKING_DIRECTORYcdWORKING_DIRECTORY …

改进爬山算法之四:概率爬山法(Probabilistic Hill Climbing,PHC)

概率爬山法(Probabilistic Hill Climbing,PHC)是一种局部搜索算法,它结合了随机性和贪婪搜索的特点,是对爬山算法(Hill Climbing Algorithm)的一种变体或扩展。与传统的爬山法不同,PHC不是总是选择最优的邻居作为下一步的移动,而是以一定的概率选择最优邻居,同时以一…

Unity中实现人物残影效果

今天火柴人联盟3公测了&#xff0c;看到一个残影的效果&#xff0c;很有意思&#xff0c;上网查询了一下实现方式&#xff0c; 实现思路&#xff1a; 将角色的网格复制出来&#xff0c;然后放置到新建的物体的MeshFilter组件上&#xff0c;每隔几十毫秒在玩家的位置生成一个&a…

C#实现调用DLL 套壳读卡程序(桌面程序开发)

背景 正常业务已经支持 读三代卡了&#xff0c;前端调用医保封装好的服务就可以了&#xff0c;但是长护要读卡&#xff0c;就需要去访问万达&#xff0c;他们又搞了一套读卡的动态库&#xff0c;为了能够掉万达的接口&#xff0c;就需要去想办法调用它们提供的动态库方法&…

自动挡有什么优势

自动挡汽车相比手动挡汽车具有多方面的优势&#xff0c;以下是对这些优势的详细阐述&#xff1a; 一、操作简便性 无需手动换挡&#xff1a;自动挡汽车不需要驾驶员手动操作离合器和换挡杆&#xff0c;只需通过油门和刹车踏板来控制车速&#xff0c;大大降低了驾驶难度。这使…

菜鸟带新鸟——基于EPlan2022的部件库制作(3D)

设备逻辑的概念&#xff1a; 可在布局空间 中和其它对象上放置对象。可将其它对象放置在 3D 对象上。已放置的对象分到组件的逻辑结构中。 将此属性的整体标识为设备逻辑。可使用不同的功能创建和编辑设备逻辑。 设备的逻辑定义 定义 / 旋转 / 移动 / 翻转&#xff1a;组…

小程序基础 —— 07 创建小程序项目

创建小程序项目 打开微信开发者工具&#xff0c;左侧选择小程序&#xff0c;点击 号即可新建项目&#xff1a; 在弹出的新页面&#xff0c;填写项目信息&#xff08;后端服务选择不使用云服务&#xff0c;开发模式为小程序&#xff0c;模板选择为不使用模板&#xff09;&…

Android Java 版本的 MSAA OpenGL ES 多重采样

最近多次被小伙伴问到 OpenGL 多重采样&#xff0c;其实前面文章里多次讲过了&#xff0c;就是构建2个缓冲区&#xff0c;多重采样缓冲区和目标解析缓冲区。 代码流程 // Framebuffer IDs private int msaaFBO; private int msaaColorBuffer; private int msaaDepthBuffer;pr…

Markdown语法字体字号讲解

学习目录 语法详解改变字体样式[电脑要自带该样式字体]改变局部字号全局字体字号的设置使用场景及应用实例 > 快来试试吧&#x1f603; &#x1f447; &#x1f447; &#x1f448;点击该图片即可跳转至Markdown学习网站进行 Markdown语法字体字号讲解&#x1f448;点击这里…