【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.rhkb.cn/news/496864.html

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

相关文章

Wend看源码-Java-集合学习(List)

摘要 本篇文章深入探讨了基于JDK 21版本的Java.util包中提供的多样化集合类型。在Java中集合共分类为三种数据结构&#xff1a;List、Set和Queue。本文将详细阐述这些数据类型的各自实现&#xff0c;并按照线程安全性进行分类&#xff0c;分别介绍非线程安全与线程安全的实现方…

OpenCV-Python实战(6)——图相运算

一、加法运算 1.1 cv2.add() res cv2.add(img1,img2,dstNone,maskNone,dtypeNone) img1、img2&#xff1a;要 add 的图像对象。&#xff08;shape必须相同&#xff09; mask&#xff1a;图像掩膜。灰度图&#xff08;维度为2&#xff09;。 dtype&#xff1a;图像数据类型…

41 stack类与queue类

目录 一、简介 &#xff08;一&#xff09;stack类 &#xff08;二&#xff09;queue类 二、使用与模拟实现 &#xff08;一&#xff09;stack类 1、使用 2、OJ题 &#xff08;1&#xff09;最小栈 &#xff08;2&#xff09;栈的弹出压入序列 &#xff08;3&#xf…

运行StableDiffusionInpaintPipeline的Example时报错:OSError: Cannot load model runwayml/stable-diffusion-...

项目地址&#xff1a; https://huggingface.co/docs/diffusers/api/pipelines/stable_diffusion/inpainthttps://huggingface.co/docs/diffusers/api/pipelines/stable_diffusion/inpaint在云服务器端运行下面给出的Example的时候出现报错&#xff1a; (myconda) rootwnyrpE:…

JDK高频面试题(包重点)

一、什么是JDK JDK&#xff08;Java Development Kit&#xff09;即 Java 开发工具包&#xff0c;是 Java 编程的基础与核心&#xff0c;由 Sun Microsystems&#xff08;现归属于 Oracle 公司 &#xff09;开发&#xff0c;主要作用如下&#xff1a; 1、提供编译环境 它包含了…

pikachu靶场搭建详细步骤

一、靶场下载 点我去下载 二、靶场安装 需要的环境&#xff1a; mysqlApaches&#xff08;直接使用小皮面板Phpstudy&#xff1a;https://www.xp.cn/&#xff09;&#xff0c;启动他们 设置网站&#xff0c;把靶场的路径对应过来 对应数据库的信息 由于没有核对数据库的信…

第P4周:猴痘病识别

目录 前言一、我的环境二、代码实现1. 前期准备1.1 设置GPU1.2 导入数据1.3 划分数据集 2. 构建简单的CNN网络3. 训练模型3.1 设置超参数3.2 编写训练函数3.3 编写测试函数3.4 正式训练 4. 结果可视化4.1 Loss与Accuracy图4.2 指定图片进行预测 5. 保存并加载模型 三、学习体会…

ElasticSearch - 深入解析 Elasticsearch Composite Aggregation 的分页与去重机制

文章目录 Pre概述什么是 composite aggregation&#xff1f;基本结构after 参数的作用问题背景&#xff1a;传统分页的重复问题after 的设计理念响应示例 after 如何确保数据不重复核心机制Example步骤 1: 创建测试数据创建索引插入测试数据 步骤 2: 查询第一页结果查询第一页返…

如何用WPS AI提高工作效率

对于每位职场人而言&#xff0c;与Word、Excel和PPT打交道几乎成为日常工作中不可或缺的一部分。在办公软件的选择上&#xff0c;国外以Office为代表&#xff0c;而在国内&#xff0c;WPS则是不可忽视的一大选择。当年一代天才程序员求伯君创造了WPS&#xff0c;后面雷军把它装…

深度学习中的并行策略概述:1 单GPU优化

深度学习中的并行策略概述&#xff1a;1 单GPU优化 1 Training Larger Models on a Single GPU 在讨论模型的“扩展”时&#xff0c;往往会想到在多个GPU或多台机器上进行模型训练。不过&#xff0c;即便是在单个GPU上&#xff0c;也存在多种方法来训练更大规模的模型并提升…

Go+chromedp实现Web UI自动化测试

1.为什么使用go进行UI自动化测试&#xff1f; 速度&#xff1a;Go速度很快&#xff0c;这在运行包含数百个UI测试的测试套件时是一个巨大的优势 并发性&#xff1a;可以利用Go的内置并发性(goroutines)来并行化测试执行 简单&#xff1a;Go的简约语法允许您编写可读且可维护…

2、C#基于.net framework的应用开发实战编程 - 设计(二、三) - 编程手把手系列文章...

二、设计&#xff1b; 二&#xff0e;三、构建数据库&#xff1b; 此例子使用的是SQLite数据库&#xff0c;所以数据库工具用的SQLiteStudio x64&#xff0c;这个是SQLite专用的数据库设计管理工具&#xff0c;其它的数据库管理工具比如DBeaver的使用请见实战工具系列文章。 1、…

2011-2020年各省城镇职工基本医疗保险年末参保人数数据

2011-2020年各省城镇职工基本医疗保险年末参保人数数据 1、时间&#xff1a;2011-2020年 2、来源&#xff1a;国家统计局 3、指标&#xff1a;省份、时间、城镇职工基本医疗保险年末参保人数 4、范围&#xff1a;31省 5、指标解释&#xff1a;参保人数指报告期末按国家有关…

Github优质项目推荐(第九期)

文章目录 Github优质项目推荐&#xff08;第九期&#xff09;一、【tldraw】&#xff0c;37.1k stars - 在 React 中创建无限画布体验的库二、【zapret】&#xff0c;9.1k stars - 独立&#xff08;无需第三方服务器&#xff09;DPI 规避工具三、【uBlock】&#xff0c;48.3k s…

Web安全攻防入门教程——hvv行动详解

Web安全攻防入门教程 Web安全攻防是指在Web应用程序的开发、部署和运行过程中&#xff0c;保护Web应用免受攻击和恶意行为的技术与策略。这个领域不仅涉及防御措施的实现&#xff0c;还包括通过渗透测试、漏洞挖掘和模拟攻击来识别潜在的安全问题。 本教程将带你入门Web安全攻防…

KOI技术-事件驱动编程(前端)

1 “你日渐平庸&#xff0c;甘于平庸&#xff0c;将继续平庸。”——《以自己喜欢的方式过一生》 2. “总是有人要赢的&#xff0c;那为什么不能是我呢?”——科比布莱恩特 3. “你那么憎恨那些人&#xff0c;和他们斗了那么久&#xff0c;最终却要变得和他们一样&#xff0c;…

嵌入式Linux QT+OpenCV基于人脸识别的考勤系统 项目

此项目是基于人脸识别的考勤系统开发&#xff0c;包括如下模块&#xff1a; 1、人脸识别考勤系统GUI界面设计&#xff0c;包括&#xff1a; &#xff08;1&#xff09;Qt环境(window环境/linux环境) &#xff1b; &#xff08;2&#xff09;Qt工程创建分析&#xff1b; &am…

UGUI简单动画制作

一、最终效果 UI简单动画制作 二、制作过程 1、打开动画制作窗口 2、新建一个动画 3、给一个对象制作动画 4、创建动画控制器进行不同动画变换控制 5、书写脚本&#xff0c;通过按钮来进行不同动画切换 using System.Collections; using System.Collections.Generic; using U…

Windows Powershell实战指南(未完成)

目前只作简单了解&#xff0c;开始吧。 一、初识Powershell 目标 初步认识 Powershell和其集成环境 Ise&#xff0c;学会基本设置 实验 我们从简单的例子开始&#xff1a;希望你能从控制台和ISE的配置中实现相同的结果。然后按照下面五步进行。 &#xff08;1&#xff09;选…

PyQt实战——实现可视化音频播放器(十三)

系类往期文章&#xff1a; PyQt5实战——多脚本集合包&#xff0c;前言与环境配置&#xff08;一&#xff09; PyQt5实战——多脚本集合包&#xff0c;UI以及工程布局&#xff08;二&#xff09; PyQt5实战——多脚本集合包&#xff0c;程序入口QMainWindow&#xff08;三&…