Flutter Web 跨域問題解決方案

yk3372發表於2020-03-02

最近對Flutter Web產生了興趣,之前一直在用Flutter寫客戶端,感覺寫的很爽,既然Flutter對Web也進行了支援,我為啥不寫一個web的來玩一下呢? 然後著手寫,靜態頁面寫起來基本沒啥問題,可是想加介面的時候,卻遇到了瀏覽器跨域問題,很榮幸解決掉了,廢話不多說,下面來分享下如何解決的吧:


前置條件:

待請求介面:https://developer.mozilla.org/api/v1/whoami 這裡我們拿這個介面來試驗

正常我們使用dio訪問:

Response response = await dio.get("https://developer.mozilla.org/api/v1/whoami");

一定會遇到這個問題:

Flutter Web 跨域問題解決方案

很明顯,瀏覽器給限制跨域了。怎麼解決呢?


解決方案其實蠻多的,對純前端來說方案很多,Flutter呢,我比較推薦的這幾個方法是:

  1. chrome 安裝這個外掛 外掛地址

安裝後,簡單配置下下面圖中的一些值即可,主要就是

Request headers:要代理的地址,
Response headers:*,
Access-Control-Allow-Headers:true
複製程式碼

Flutter Web 跨域問題解決方案
然後在Web頁面開啟對應的開關即可。

  1. 配置Nginx,配置太多這裡就不說了,網上很多。
  2. 接下來我們重點講一下flutter特有的方式,參考思路來源前端的解決方案,先來看下前端的方案,對應文章地址:juejin.im/post/5d1ecb…

Flutter Web 跨域問題解決方案

看到了這裡,我正好週末看到dart可以寫伺服器,那是不是可以參考下? 於是我找到了這個:

shelf_proxy 簡單封裝了一下: shelf

很早前我還看到過這個,不知幹啥的,現在用到了,才知道原來如此,雖然star不多,但卻是Dart官方的,用於本地除錯介面使用,還是很靠譜的。

對應到我專案裡怎麼用的呢?我們來看下 關鍵程式碼

import 'package:shelf/shelf_io.dart' as shelf_io;
import 'package:shelf_proxy/shelf_proxy.dart';

//前端頁面訪問本地域名
const String LocalHost = 'localhost';

//前端頁面訪問本地埠號
const int LocalPort = 4040;

//目標域名,這裡我們將要請求火狐的這個地址
const String TargetUrl = 'https://developer.mozilla.org';

Future main() async {
  var server = await shelf_io.serve(
    proxyHandler(TargetUrl),
    LocalHost,
    LocalPort,
  );
  // 新增上跨域的這幾個header
  server.defaultResponseHeaders.add('Access-Control-Allow-Origin', '*');
  server.defaultResponseHeaders.add('Access-Control-Allow-Credentials', true);

  print('Serving at http://${server.address.host}:${server.port}');
}
複製程式碼

然後我把上面的這段程式碼,儲存到前端的一個資料夾裡面,放在lib/server/cors.dart,然後開啟命令列,執行:dart ./lib/server/cors.dart,代理伺服器啟動了!

接下來,我們前端的flutter程式碼,也就是上面的請求,改成

Response response = await dio.get("http://localhost:4040/api/v1/whoami");

接下來點請求,果然正常拿到結果:

Flutter Web 跨域問題解決方案

到這為止,跨域的問題完美解決,全部用dart來解決了(這是我最想要的)!?

當然了,這只是個demo級別的程式碼,還有很多細的東西可以重寫定製。 如果大家有什麼更好的建議,歡迎告訴我哦~

ps:為什麼要把這個服務檔案放在前端,目的是依賴庫可以直接用,再就是執行代理服務也方便,後面可以跟執行程式碼一起啟動,比如寫個批處理是吧。。。

相關文章