Flutter 程序在 Chrome 上运行正常,但在 Web 服务器上无法正常运行
Posted
技术标签:
【中文标题】Flutter 程序在 Chrome 上运行正常,但在 Web 服务器上无法正常运行【英文标题】:flutter program work okay on chrome, but cannot work correctly on web server 【发布时间】:2020-09-16 13:36:16 【问题描述】:我是 Flutter 的新手,编写了以下 Flutter 程序来获取客户端 IP 地址和位置。我正在呼叫“http://ip-api.com/json”以获取 IP 地址和位置信息。该程序通过使用设备“chrome”和“web server”可以正常工作,我可以在页面上打印客户端的位置。 . 当我部署到 github 网页或 firebase 托管时,程序永远显示“加载循环”。程序部署到github web服务器(或其他web服务器)后,似乎无法获取ip地址。
一旦我将程序部署到 Github html 页面或 firebase 托管,我发现该程序抛出“XMLHTTPRequest 错误”。它在本地 Web 服务器或 chrome 上运行良好。对此有何建议?非常感谢。
import 'dart:async';
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
class IP_info
final String IP;
final String city;
final String ZIP;
final String st_code;
final String state_name;
final String country_code;
final String country_name;
IP_info(this.IP, this.city, this.st_code,this.ZIP,
this.state_name,this.country_code,this.country_name);
factory IP_info.fromJson(Map<String, dynamic> json)
return IP_info(
IP:json['query'],
ZIP:json['zip'],
city:json['city'],
country_code:json['countryCode'],
st_code:json['region'],
country_name:json['country_name'],
state_name:json['regionName'],
);
void main()
runApp(MaterialApp(
title: 'Covid 19 cases near you',
home: MyApp()
),
);
class MyApp extends StatefulWidget
@override
State<StatefulWidget> createState() => MyAppState();
class MyAppState extends State<MyApp>
bool _isLoading = false;
IP_info ip_info;
@override
void initState()
_isLoading=true;
_getPublicIP();
_getPublicIP() async
try
const url = 'http://ip-api.com/json';
final response = await http.get(url);
if (response.statusCode == 200)
ip_info = IP_info.fromJson(json.decode(response.body));
print(ip_info.toString());
setState(()
_isLoading = false;
);
else
// The request failed with a non-200 code
print(response.statusCode);
print(response.body);
catch (e)
print(e);
@override
Widget build(BuildContext context)
return Scaffold(
appBar: AppBar(title: Text('Testing IP address'), ),
body: Container(
padding: const EdgeInsets.all(8.0),
decoration: BoxDecoration(
color: Colors.white,
),
child: _isLoading? Center(
child: Column(children: [
CircularProgressIndicator(),
SizedBox(height: 10,),
Text("Loading your location infomation ...", style: TextStyle(color: Colors.blueAccent),),
]
)
)
: new Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.center ,
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget> [
Text('You are in $ip_info.city $ip_info.state_name ',
style: TextStyle(
fontWeight: FontWeight.bold,),
),
],
),
)
);
【问题讨论】:
【参考方案1】:这可能是因为只为发布构建生成的服务工作者文件。服务工作文件的 credentials: 'include'
部分会中断所有没有Access-Control-Allow-Origin
或值为*
的请求,这些请求都是公共API。
上面有一个issue,据说master里已经修复了,还没有发布。因此,您目前可以做的一些解决方法是在每次构建后手动删除credentials
部分或取消注册服务工作者。
如果您仍想使用 Service Worker,可以通过以下方法移除该部分。 build/web
文件夹内应该有一个 flutter_service_worker.js
文件。您会发现凭证部分是 fetch
函数的第二个参数。您可以删除该参数。但这样做的坏处是每次构建后您都必须手动删除该部分,这既不是程序化的也不是有效的。
解决此问题的最佳方法是完全取消注册 Service Worker。您可以通过从 web/index.html
文件中删除此脚本部分来做到这一点。
<script>
if ("serviceWorker" in navigator)
window.addEventListener("load", function()
navigator.serviceWorker.register("/flutter_service_worker.js");
);
</script>
【讨论】:
非常感谢 Frenco 看一看这个。我在代码中添加了“CircularProgressIndicator()”函数(请参见上文)。但是在我部署到 Web 服务器后,代码仍然无法正常工作。我正在使用主通道进行颤动。您能建议我可以删除哪个程序“凭据:'包含'”吗?感谢您的指示。 嗨,Frenco,我在 web/index.html 文件中注释掉了 service worker 部分,但是一旦我将代码部署到 github html 或 firebase 托管,我仍然得到一个空白页面。 我认为你是对的。可能与一些设置问题有关。 @JoeZhouweb/index.html
文件更新后你又重建了对吧?因为如果没有,你必须这样做。
感谢弗朗科!一旦我用“flutter build web”重建,web/index.html 就会用“Service Worker”部分重新生成。我这里是菜鸟。 “flutter build web”是正确的构建命令吗?【参考方案2】:
我切换到geolocation-db.com/json(而不是使用'ip-api.com/json)来获取客户端节点的位置信息,它可以工作!我认为这与服务器端有关。我认为这可能与网络请求必须是 https 而不是 http 有关。
【讨论】:
以上是关于Flutter 程序在 Chrome 上运行正常,但在 Web 服务器上无法正常运行的主要内容,如果未能解决你的问题,请参考以下文章
如何从 IDE 在移动 chrome 上运行 Flutter Web
Flutter Application release apk 在真实设备上无法正常工作
Flutter Web - 如何在桌面上的 Chrome 中测试 Flutter Web 应用程序打开?
在 Web 上运行的 Flutter 应用程序失败并出现错误:只有 JS 互操作成员可能是“外部的”