【问题标题】:flutter program work okay on chrome, but cannot work correctly on web serverFlutter 程序在 Chrome 上运行正常,但在 Web 服务器上无法正常运行
【发布时间】: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,),
              ),

            ],
          ),
        )
    );
  }

【问题讨论】:

    标签: google-chrome flutter web dart server


    【解决方案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 托管,我仍然得到一个空白页面。
    • 我认为你是对的。可能与一些设置问题有关。
    • @JoeZhou web/index.html 文件更新后你又重建了对吧?因为如果没有,你必须这样做。
    • 感谢弗朗科!一旦我用“flutter build web”重建,web/index.html 就会用“Service Worker”部分重新生成。我这里是菜鸟。 “flutter build web”是正确的构建命令吗?
    【解决方案2】:

    我切换到geolocation-db.com/json(而不是使用'ip-api.com/json)来获取客户端节点的位置信息,它可以工作!我认为这与服务器端有关。我认为这可能与网络请求必须是 https 而不是 http 有关。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2019-05-21
      • 1970-01-01
      • 2020-01-21
      • 1970-01-01
      • 2021-03-14
      • 1970-01-01
      • 2018-04-29
      相关资源
      最近更新 更多