首页 > 解决方案 > Flutter / Dart 没有从本地托管的烧瓶 api 返回值

问题描述

使用 IOS、Visual Studio Code、Flask、VirtualEnv....

我刚开始玩 Flask 和 Flutter。我已经创建了一个本地托管的烧瓶服务器,它通过 api 返回用户,并且我正在尝试使用带有 USB 连接的 IOS 设备的 Flutter 访问 api。当我尝试托管在互联网上的 api 时,我在手机上得到了输出,但是当我指向本地 API 时,它看起来不像是在访问服务器,我在烧瓶服务器日志中没有得到任何响应,表明发出了请求。我究竟做错了什么?

通过我的浏览器,我可以导航到 127.0.0.1:5000/users 并获得以下输出。我希望这会出现在我的手机上:

[{“姓名”:“尼克”,“年龄”:42,“职业”:“网络工程师”},{“姓名”:“埃尔文”,“年龄”:32,“职业”:“业务分析师”} , {“姓名”:“尼克”,“年龄”:22,“职业”:“测试分析​​师”}]

这是我的烧瓶服务器代码:

from flask import Flask
from flask_restful import Api, Resource, reqparse
from flask import jsonify
import json

app = Flask(__name__)
api = Api(app)

users = [
    {
        "name": "Nick",
        "age": 42,
        "occupation": "Network Engineer"
    },
    {
        "name": "Elvin",
        "age": 32,
        "occupation": "Business Analyst"
    },
    {
        "name": "Nick",
        "age": 22,
        "occupation": "Test Analyst"
    }
]

class User(Resource):
    def get(self, name):
        for user in users:
            if(name ==user["name"]):
                return user, 200
        return "User not found@, 404"

    def post(self, name):
        parser = reqparse.RequestParser()
        parser.add_argument("age")
        parser.add_argument("occupation")
        args = parser.parse_args()

        for user in users:
            if(name == user["name"]):
                return "User with name {} already exist".format(name), 400

        user = {
            "name": name,
            "age": args["age"],
            "occupation": args["occupation"]
        }
        users.append(user)
        return user, 201

    def put(self, name):
        parser = reqparse.RequestParser()
        parser.add_argument("age")
        parser.add_argument("occupation")
        args = parser.parse_args()

        for user in users:
            if(name == user["name"]):
                user["age"] = args["age"]
                user["occupation"] = args["occupation"]
                return user, 200

        user = {
            "name": name,
            "age": args["age"],
            "occupation": args["occupation"]        
        }
        users.append(user)
        return user, 201

    def delete(self, name):
        global users
        users = [user for user in users if user["name"] != name]
        return "{} is deleted.".format(name), 200

@app.route('/users', methods=['GET'])
def getUsers():
    return json.dumps(users)


api.add_resource(User, "/user/<string:name>")
app.run(debug=True)

这是我的 pubspec.yaml

name: apitest2
description: A new Flutter project.

 version: 1.0.0+1

environment:
  sdk: ">=2.1.0 <3.0.0"

dependencies:
  flutter:
    sdk: flutter
  http: ^0.12.0+2

  cupertino_icons: ^0.1.2

dev_dependencies:
  flutter_test:
    sdk: flutter

flutter:


  uses-material-design: true

这是我的 API.dart - 从 127... 更改为我的本地 IP 地址并没有什么不同

import 'dart:async';
import 'package:http/http.dart' as http;

const baseUrl = "http://127.0.0.1:5000";
//const baseUrl = "http://192.168.86.24:5000";
//const baseUrl = "https://jsonplaceholder.typicode.com";

class API {
  static Future getUsers() {
    var url = baseUrl + "/users";
    return http.get(url);
  }
}

这是我的 User.dart

class User {
  String name;
  int age;
  String occupation;

  User(String name, int age, String occupation) {
    this.name = name;
    this.age = age;
    this.occupation = occupation;
  }

  User.fromJson(Map json)
      : name = json['name'],
        age = json['age'],
        occupation = json['occupation'];

  Map toJson() {
    return {'name': name, 'age': age, 'occupation': occupation};
  }
}

这是我的 Main.dart

import 'dart:convert';
import 'package:apitest2/API.dart';
import 'package:apitest2/User.dart';
import 'package:flutter/material.dart';

void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
  @override
  build(context) {
    return MaterialApp(
      debugShowCheckedModeBanner: true,
      title: 'My Http App',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyListScreen(),
    );
  }
}

class MyListScreen extends StatefulWidget {
  @override
  createState() => _MyListScreenState();
}

class _MyListScreenState extends State {
  var users = new List<User>();

  _getUsers() {
    API.getUsers().then((response) {
      setState(() {
        Iterable list = json.decode(response.body);
        users = list.map((model) => User.fromJson(model)).toList();
      });
    });
  }

  initState() {
    super.initState();
    _getUsers();
  }

  dispose() {
    super.dispose();
  }

  @override
  build(context) {
    return Scaffold(
        appBar: AppBar(
          title: Text("User List"),
        ),
        body: ListView.builder(
          itemCount: users.length,
          itemBuilder: (context, index) {
            return ListTile(title: Text(users[index].name));
          },
        ));
  }
}

标签: pythoniosapiflaskflutter

解决方案


大意

  • 如果我们想从连接到我们 LAN 的其他计算机或设备向我们的 API 发出 HTTP 请求,我们应该使用开发计算机 IP 地址,0.0.0.0(用于 IPv4 配置)或 ::(用于 IPv6 配置)作为所需的 IP 地址对于我们的开发服务器。
  • 如果我们指定 0.0.0.0 作为 IPv4 配置所需的 IP 地址,开发服务器将侦听端口 5000 上的每个接口。

请参阅以下解决方案,它也解决了类似的问题:

https://stackoverflow.com/a/62371660/10031056


推荐阅读