android - Flutter 返回空字符串 - HTTP(S) GET 请求

标签 android networking get dart flutter

我有一个 HTTP(S) GET 请求,该请求在 java(Android sdk)和 Python 中运行良好,但是当我尝试将其移植到 flutter 时,它返回一个空字符串。 它应该返回一个 JSON,其中包含大约 2MB 的数据。

这是Python代码:

import http.client

HOST, PORT = 'kretaglobalmobileapi.ekreta.hu', 443
headers = {"apiKey": "7856d350-1fda-45f5-822d-e1a2f3f1acf0", "Connection": "keep-alive",
           "Accept": "application/json", "HOST": "kretaglobalmobileapi.ekreta.hu"}

conn = http.client.HTTPSConnection(host=HOST, port=PORT)
conn.request("GET", "/api/v1/Institute", headers=headers)

response = conn.getresponse()

data = response.read()
print(data)

conn.close()

对于 Flutter 版本,我尝试了两种不同的方法,但没有成功。

第一种方法:

import 'dart:async';
import 'dart:convert' show utf8, json;
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;

Future<http.Response> fetchPost() {
  return http.get(
    "https://kretaglobalmobileapi.ekreta.hu/api/v1/Institute",
    // Send authorization headers to your backend
      headers : {"apiKey": "7856d350-1fda-45f5-822d-e1a2f3f1acf0", "Connection": "keep-alive",
        "Accept": "application/json", "HOST": "kretaglobalmobileapi.ekreta.hu"}
  );
}

void login() async {

  print((await fetchPost()).body);
  print((await fetchPost()).body.length);

}

它返回:

Performing full restart...
Restarted app in 3,648ms.
I/flutter (18739): 
I/flutter (18739): 0

第二:

Future<Map<String, dynamic>> getInstitutes(HttpClient client) async {
  final String url = "https://kretaglobalmobileapi.ekreta.hu/api/v1/Institute";

  final HttpClientRequest request = await client.getUrl(Uri.parse(url))
    ..headers.add("Accept", "application/json")
    ..headers.add("HOST", "kretaglobalmobileapi.ekreta.hu")
    ..headers.add("apiKey", "7856d350-1fda-45f5-822d-e1a2f3f1acf0")
    ..headers.add("Connection", "keep-alive");

  final HttpClientResponse response = await request.close();
  print(json.decode(await response.join()));

  return json.decode(await response.transform(utf8.decoder).join());
}

我在这里省略了 GUI 和样板代码,完整的代码位于 pastebin

更新:问题是,我连接的 API 使用了过时的 HTTP 标准。我告诉支持人员这件事,他们告诉我他们不愿意修复它,所以我必须创建一个新的网络服务器(可能用 Python)来在客户端和 API 之间运行。另一种选择是使用原生 Android 和 iOS 代码,它们有望支持区分大小写的 header 。 呵呵,这一切都是因为他们无法将大写“K”更改为小写“k”。

最佳答案

对于任何 HTTP 请求,最好测试 HTTP 响应代码。在您的情况下,您将收到 403 Forbidden,因此您的凭据或 API key 不会被服务器接受。

在第一种方法中,您实际上向服务器发送两个请求 - 每个等待一个。考虑更改为:

  http.Response r = await fetchPost();
  print(r.statusCode);
  print(r.body.length);

编辑 - 服务器未接受您的 API key ,服务器的行为方式不符合标准。

Dart HttpClient(在第二种方法中直接使用,在第一种方法中间接使用)恰好将所有请求 header 小写。这是完全有效的,因为 RFC 7230 规定“每个 header 字段都包含一个不区分大小写的字段名称,后跟冒号(“:”)、可选的前导空格、字段值和可选的尾随空白。".

因此,即使您添加 header "apiKey": "7856d...,网络上发出的仍是 apikey: 7856d...

但是(这是您不喜欢的一点),HTTP 服务器似乎是非标准的,不会接受 apikey 而不是 apiKey 。尝试更改 Python 代码以使用 apikeyAPIKEY,您会得到 403。

(请注意,HTTPS 没有区别,使用 HTTP 会得到相同的结果。)

看来您需要将此作为错误报告给 Kreta。

关于android - Flutter 返回空字符串 - HTTP(S) GET 请求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50199711/

相关文章:

android - ListFragment 不显示当前时间的变化

c++ - Qt:服务器从套接字接收数据

flutter - 无法将类型 'bool?' 的值分配给类型 'bool' 的变量,因为 'bool?' 可以为 null,而 'bool' 则不能

AngularJS HTTP.get 未在网络选项卡中触发/显示

networking - TCP 是在每个数据包上发送 SYN/ACK 还是仅在第一个连接上发送?

php - 如何在我的示例中使用 urlencode()?

android - AdMob Adview 到包含内部类的类

android - Intellij IDEA 显示错误 : could not create the java virtual machine

android - 支持多分辨率设备Android

linux - 如果 dhcp 失败,设置保存的静态 IP 地址