无法向 python 本地服务器发送 flutter GET 请求

Unable to send flutter GET request to python local server

我用 TextField() 和一个 Text() 小部件制作了一个简单的 flutter web 应用程序。当我按下按钮时,我希望它向使用 python 制作的简单 Flask 应用程序发送查询,在那里它将 returns 倒置文本,然后我将其显示在文本小部件上。

NOTE: Inverting text is not the actual task. Its just to check if I'm able to get the data.

Python代码:

当我在 chrome 上 运行 时,此代码有效。

#performing flask imports
from flask import Flask,jsonify
from flask.globals import request


app = Flask(__name__) #intance of our flask application 

#Route '/' to facilitate get request from our flutter app
@app.route("/api",methods=["GET"])
def function():
    d = {}
    text = str(request.args["Query"])
    text = text[::-1]
    d["query"] = text
    return jsonify(d)

if __name__ == "__main__":
    app.run()

颤动代码:

main.dart

import 'package:flutter/material.dart';
import 'api.dart';
import 'dart:convert';

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

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  String url;

  var data;

  String queryText = "Query";

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(
          title: Text("PYTHON AND FLUTTER"),
        ),
        body: Column(
          children: <Widget>[
            Padding(
              padding: const EdgeInsets.all(10.0),
              child: TextField(
                onChanged: (value) {
                  url = "http://10.0.2.2:5000/api?Query=" + value.toString();
                },
                decoration: InputDecoration(
                    hintText: "Search Anything Here",
                    suffixIcon: GestureDetector(
                        onTap: () async {
                          data = await getData(url);
                          var decodedData = jsonDecode(data);
                          setState(() {
                            queryText = decodedData["Query"];
                          });
                        },
                        child: Icon(Icons.search))),
              ),
            ),
            Padding(
              padding: const EdgeInsets.all(10.0),
              child: Text(
                queryText,
                style: TextStyle(fontSize: 30.0, fontWeight: FontWeight.bold),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

api.dart

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

Future getData(url) async {
  http.Response response = await http.get(url);
  return response.body;
}

我遵循了以下教程:This Youtube Video

我正在 运行通过命令提示符和 flutter 应用程序 VScode 设置 python 代码。

我收到以下错误:

Error: Expected a value of type 'Uri', but got one of type 'String'
    at Object.throw_ [as throw] (http://localhost:50523/dart_sdk.js:5348:11)
    at Object.castError (http://localhost:50523/dart_sdk.js:5319:15)
    at Object.cast [as as] (http://localhost:50523/dart_sdk.js:5635:17)
    at Function.as_C [as as] (http://localhost:50523/dart_sdk.js:5263:19)
    at getData (http://localhost:50523/packages/word_prediction/api.dart.lib.js:29:47)
    at getData.next (<anonymous>)
    at runBody (http://localhost:50523/dart_sdk.js:39211:34)
    at Object._async [as async] (http://localhost:50523/dart_sdk.js:39242:7)
    at Object.getData (http://localhost:50523/packages/word_prediction/api.dart.lib.js:28:18)
    at main._MyAppState.new.<anonymous> (http://localhost:50523/packages/word_prediction/main.dart.lib.js:422:48)
    at Generator.next (<anonymous>)
    at runBody (http://localhost:50523/dart_sdk.js:39211:34)
    at Object._async [as async] (http://localhost:50523/dart_sdk.js:39242:7)
    at http://localhost:50523/packages/word_prediction/main.dart.lib.js:421:210
    at tap.TapGestureRecognizer.new.invokeCallback (http://localhost:50523/packages/flutter/src/gestures/recognizer.dart.lib.js:203:18)
    at tap.TapGestureRecognizer.new.handleTapUp (http://localhost:50523/packages/flutter/src/gestures/tap.dart.lib.js:417:40)
    at tap.TapGestureRecognizer.new.[_checkUp] (http://localhost:50523/packages/flutter/src/gestures/tap.dart.lib.js:223:12)
    at tap.TapGestureRecognizer.new.acceptGesture (http://localhost:50523/packages/flutter/src/gestures/tap.dart.lib.js:199:23)
    at arena.GestureArenaManager.new.sweep (http://localhost:50523/packages/flutter/src/gestures/arena.dart.lib.js:222:31)
    at binding.WidgetsFlutterBinding.new.handleEvent (http://localhost:50523/packages/flutter/src/gestures/binding.dart.lib.js:402:27)
    at binding.WidgetsFlutterBinding.new.dispatchEvent (http://localhost:50523/packages/flutter/src/gestures/binding.dart.lib.js:381:24)
    at binding.WidgetsFlutterBinding.new.dispatchEvent (http://localhost:50523/packages/flutter/src/rendering/layer.dart.lib.js:6107:13)
    at binding.WidgetsFlutterBinding.new.[_handlePointerEventImmediately] (http://localhost:50523/packages/flutter/src/gestures/binding.dart.lib.js:352:14)
    at binding.WidgetsFlutterBinding.new.handlePointerEvent (http://localhost:50523/packages/flutter/src/gestures/binding.dart.lib.js:325:43)
    at binding.WidgetsFlutterBinding.new.[_flushPointerEventQueue] (http://localhost:50523/packages/flutter/src/gestures/binding.dart.lib.js:314:14)
    at binding.WidgetsFlutterBinding.new.[_handlePointerDataPacket] (http://localhost:50523/packages/flutter/src/gestures/binding.dart.lib.js:304:65)
    at Object.invoke1 (http://localhost:50523/dart_sdk.js:185426:7)
    at _engine.EnginePlatformDispatcher.__.invokeOnPointerDataPacket (http://localhost:50523/dart_sdk.js:165747:15)
    at _engine.PointerBinding.__.[_onPointerData] (http://localhost:50523/dart_sdk.js:166405:49)
    at http://localhost:50523/dart_sdk.js:166863:28
    at http://localhost:50523/dart_sdk.js:166816:16
    at http://localhost:50523/dart_sdk.js:166509:11

我不知道我做错了什么。

试试这个:

Future getData(String url) async {
  var response = await http.get(Uri.parse(url));
  return response.body;
}

沿着 Ουιλιαμ Αρκευα 提到的这个变化

还有一个问题: 当我使用断点时,它显示 blinding.dart

的文件调用

这是因为 CORS。

跨源请求 (CORS) 错误,这是因为我没有在我的服务器中设置它。

如果您的 Flutter Web 应用程序 运行 与您 api 所在的服务器 运行 不在同一个域中,则尤其如此。即使在同一台机器上,您也必须允许来自特定域和端口的请求。

这可以通过在 flask 代码中添加以下行来完成:

response.headers.add("Access-Control-Allow-Origin", "*")

response.headers.add("Access-Control-Allow-Credentials", "true")

因此更新后的代码将是:

#performing flask imports
from flask import Flask,jsonify
from flask.globals import request


app = Flask(__name__) #intance of our flask application 

#Route '/' to facilitate get request from our flutter app
@app.route("/api",methods=["GET"])
def word_predictor():
    d = {}
    text = str(request.args["Query"])
    text = text[::-1]
    d["Query"] = text
    response = jsonify(d)
    response.headers.add("Access-Control-Allow-Origin", "*")
    response.headers.add("Access-Control-Allow-Credentials", "true")
    return response

if __name__ == "__main__":
    app.run()

并且,通过这两项更改,代码可以正常工作。