【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.pswp.cn/web/64262.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/64262.shtml
英文地址,請注明出處:http://en.pswp.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;點擊這里…