программа flutter работает нормально на chrome, но не может корректно работать на веб-сервере - PullRequest
0 голосов
/ 29 мая 2020

Я новичок в флаттере и написал следующую программу флаттера, чтобы получить IP-адрес и местоположение клиента. Я звоню «http://ip-api.com/json» для получения информации об IP-адресе и местоположении. Программа работает нормально, используя устройство «chrome» и «веб-сервер», я могу распечатать местоположение клиента на странице.
. Когда я развернулся на веб-странице github или хостинге firebase, программа всегда показывала «круг загрузки». Кажется, что программа не может получить IP-адрес после того, как она была развернута на веб-сервере github (или другом веб-сервере).

Я обнаружил, что программа выдает ошибку XMLHTTPRequest после того, как я развернул ее на странице Github html или на хостинге firebase. Он отлично работает на локальном веб-сервере или 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,),
              ),

            ],
          ),
        )
    );
  }

Ответы [ 2 ]

0 голосов
/ 01 июня 2020

Я переключился на geolocation-db.com/json (вместо использования ip-api.com/json), чтобы получить информацию о местоположении клиентского узла, и это работает! Думаю, это связано с серверной частью. Я думаю, это может быть связано с тем, что веб-запрос должен быть https вместо http.

0 голосов
/ 29 мая 2020

Вероятно, это из-за того, что файл сервис-воркера, созданный только для сборки выпуска. Часть { credentials: 'include' } рабочего файла службы разбивает все запросы без Access-Control-Allow-Origin или со значением *, которое является всеми API-интерфейсами publi c.

Существует проблема на это, и говорят, что это исправлено в мастере, который еще не был выпущен. Итак, некоторые обходные пути, которые вы можете сделать в настоящее время, - это удалить часть credentials вручную после каждой сборки или отменить регистрацию сервис-воркера.

Вот как вы можете удалить эту часть, если вы все еще хотите использовать сервис-воркер. Внутри папки build/web должен быть файл flutter_service_worker.js. Вы найдете эту часть учетных данных как второй аргумент функции fetch. Вы можете удалить этот аргумент. Но плохо в том, что вы должны удалять эту часть вручную каждый раз после сборки, что не является программным c или эффективным.

Лучший способ решить эту проблему - полностью отменить регистрацию сервис-воркера. Вы можете сделать это, удалив эту часть скрипта из файла web/index.html.

<script>
      if ("serviceWorker" in navigator) {
        window.addEventListener("load", function() {
          navigator.serviceWorker.register("/flutter_service_worker.js");
        });
      }
</script>
...